動態載入和解除安裝非託管 DLL
使用 DllImport
屬性時,你必須在編譯時知道正確的 dll 和方法名稱。如果你想要更靈活並在執行時決定載入哪些 dll 和方法,可以使用 Windows API 方法 LoadLibrary()
, GetProcAddress()
和 FreeLibrary()
。如果要使用的庫取決於執行時條件,這可能會有所幫助。
GetProcAddress()
返回的指標可以使用 Marshal.GetDelegateForFunctionPointer()
轉換為委託。
以下程式碼示例使用前面示例中的 myDLL.dll
演示了這一點:
class Program
{
// import necessary API as shown in other examples
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibrary(string lib);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern void FreeLibrary(IntPtr module);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr module, string proc);
// declare a delegate with the required signature
private delegate int AddDelegate(int a, int b);
private static void Main()
{
// load the dll
IntPtr module = LoadLibrary("myDLL.dll");
if (module == IntPtr.Zero) // error handling
{
Console.WriteLine($"Could not load library: {Marshal.GetLastWin32Error()}");
return;
}
// get a "pointer" to the method
IntPtr method = GetProcAddress(module, "add");
if (method == IntPtr.Zero) // error handling
{
Console.WriteLine($"Could not load method: {Marshal.GetLastWin32Error()}");
FreeLibrary(module); // unload library
return;
}
// convert "pointer" to delegate
AddDelegate add = (AddDelegate)Marshal.GetDelegateForFunctionPointer(method, typeof(AddDelegate));
// use function
int result = add(750, 300);
// unload library
FreeLibrary(module);
}
}