/// <summary>
/// Dynamically lookup a function in the dll via kernel32!GetProcAddress.
/// </summary>
/// <param name="functionName">The name of the function in the export table.</param>
/// <param name="delegateType">The Type of the delegate to be returned.</param>
/// <returns>A delegate to the unmanaged function. Returns
/// <see langword="null"/> if the function is not found.
/// </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 Delegate GetUnmanagedFunction(string functionName, Type delegateType)
{
IntPtr procAddress = NativeMethods.GetProcAddress(this.libraryHandle, functionName);
// Failure is a common case, especially for adaptive code.
if (procAddress == IntPtr.Zero)
{
return(null);
}
Delegate function = Marshal.GetDelegateForFunctionPointer(procAddress, delegateType);
return(function);
}