/// <summary> /// Constructor to load a dll and be responible for freeing it. /// </summary> /// <param name="fileName">full path name of dll to load</param> /// <exception cref="System.IO.FileNotFound">if fileName can't be found</exception> /// <remarks>Throws exceptions on failure. Most common failure would be file-not-found, or /// that the file is not a loadable image.</remarks> public UnmanagedLibrary(string fileName) { m_hLibrary = MemLibraryLoader.LoadLibrary(fileName); if (m_hLibrary.IsInvalid) { int hr = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(hr); } }
/// <summary> /// Dynamically lookup a function in the dll via kernel32!GetProcAddress. /// </summary> /// <param name="functionName">raw name of the function in the export table.</param> /// <returns>null if function is not found. Else a delegate to the unmanaged function. /// </returns> /// <remarks>GetProcAddress results are valid as long as the dll is not yet unloaded. This /// is very very dangerous to use since you need to ensure that the dll is not unloaded /// until after you're done with any objects implemented by the dll. For example, if you /// get a delegate that then gets an IUnknown implemented by this dll, /// you can not dispose this library until that IUnknown is collected. Else, you may free /// the library and then the CLR may call release on that IUnknown and it will crash.</remarks> public TDelegate GetUnmanagedFunction <TDelegate>(string functionName) where TDelegate : class { IntPtr p = MemLibraryLoader.GetProcAddress(m_hLibrary, functionName); // Failure is a common case, especially for adaptive code. if (p == IntPtr.Zero) { return(null); } Delegate function = Marshal.GetDelegateForFunctionPointer(p, typeof(TDelegate)); // Ideally, we'd just make the constraint on TDelegate be // System.Delegate, but compiler error CS0702 (constrained can't be System.Delegate) // prevents that. So we make the constraint system.object and do the cast from object-->TDelegate. object o = function; return((TDelegate)o); }
protected override bool ReleaseHandle() { return(MemLibraryLoader.FreeLibrary(handle)); }