【C#】动态加载dll程序集
很多时候我们需要用到引用其他程序集,有些程序集是.Net生成的,可以支持反编译,而C/C++程序集不支持反编译,不能再C#项目中直接引用,我们需要预先知道程序集中函数的签名,然后先声明为静态的函数,例如:
引用test.dll,该程序集包含Add方法,返回两个整型数据的和
[DllImport(@"c:\test.dll")] private static extern int Add(int a, int b);
然后再需要的时候使用
private void DoSomething() { int sum = Add(10, 20); }
但是这种方法不能改变函数的名字,下面说说如何动态添加dll程序集
1、这里需要用到windows的API来加载程序集,先引入API函数,用于加载程序集
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")] static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")] static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")] static extern bool FreeLibrary(int hModule);
2、接下来是在代码中加载程序集,得到函数指针
int hModule = LoadLibrary(@"c:\test.dll"); if (hModule == 0) return false; //得到指向Add函数的指针 IntPtr intPtr = GetProcAddress(hModule, "Add");
3、得到了函数指针,但是C#不支持指针,但是C#有委托的概念,C#中也是通过委托实现指针函数的功能的,这里也通过委托来引用
先声明一个委托
public delegate void MyAdd(int a, int b);
加载,得到委托(Marshal 在 System.Runtime.InteropServices 命名空间)
MyAdd myadd = (MyAdd)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MyAdd));
4、使用该委托
int sum = myadd(10, 20);