C#如何仅通过代码实现运行时动态加载自定义DLL并调用其方法
问题原因
你用DllImport特性导入报错是用法错了:DllImport仅用于加载C/C++等编写的非托管原生DLL,你用C#编译生成的是.NET托管类库,本身就不适用这个导入方式。
不需要在Visual Studio中提前添加引用,纯代码加载托管DLL直接用.NET内置的反射API即可实现,所有.NET版本(.NET Framework、.NET Core/.NET 5+)都支持。
实现步骤
前置检查
先确认两个前提,否则会加载失败:
- 你编译的类库DLL和当前主程序的目标框架兼容:比如主程序跑在.NET 6上,DLL不能是仅支持.NET Framework 4.8的版本;如果是跨大版本兼容,建议类库编译时目标框架选.NET Standard。
- 代码里写的DLL路径正确,建议一开始直接把DLL拷贝到主程序的bin运行目录,直接写DLL文件名调试。
通用加载方案(全.NET版本支持)
用Assembly.LoadFrom方法加载DLL,再通过反射找到对应的类和方法调用即可,示例代码如下:
using System; using System.Reflection; class Program { static void Main() { // 1. 从指定路径加载托管DLL Assembly libAssembly = Assembly.LoadFrom("MyClassLibrary.dll"); // 2. 查找目标类的类型:如果你的MyClass定义在命名空间下,格式是"命名空间.类名",没有命名空间直接写类名 Type myClassType = libAssembly.GetType("MyClass", throwOnError: true); // 3. 查找目标公开静态方法 MethodInfo writeHelloMethod = myClassType.GetMethod( "WriteHello", BindingFlags.Public | BindingFlags.Static ); // 4. 调用静态方法:静态方法不需要实例,第一个参数传null;方法无参数第二个参数传null writeHelloMethod.Invoke(null, null); } }
运行后就会正常输出Hello world。
进阶:可卸载加载(仅.NET Core 3.0/.NET 5+支持)
如果需要加载DLL用完后释放文件占用、卸载DLL不占用内存,可以用AssemblyLoadContext实现独立加载上下文:
using System; using System.IO; using System.Reflection; using System.Runtime.Loader; class Program { static void Main() { // 创建可回收的独立加载上下文 var libContext = new AssemblyLoadContext("MyLibLoadContext", isCollectible: true); try { string dllFullPath = Path.GetFullPath("MyClassLibrary.dll"); Assembly libAssembly = libContext.LoadFromAssemblyPath(dllFullPath); // 后续查找类型、调用方法的逻辑和通用方案完全一致 Type myClassType = libAssembly.GetType("MyClass", throwOnError: true); MethodInfo writeHelloMethod = myClassType.GetMethod("WriteHello", BindingFlags.Public | BindingFlags.Static); writeHelloMethod.Invoke(null, null); } finally { // 用完卸载上下文,释放DLL占用 libContext.Unload(); } } }
注意事项
- 如果
GetType返回null,优先检查类名是否写对、是否带了命名空间,命名空间和类名的大小写要完全和你定义类库时的写法一致。 - 如果要调用的是实例方法,需要先通过
Activator.CreateInstance(myClassType)创建类的实例,再把实例传给Invoke的第一个参数。 - 如果方法有入参,把参数按顺序放到object数组里传给
Invoke的第二个参数即可,比如方法需要传入一个int和一个string参数,就写new object[] { 123, "test" }。
内容的提问来源于stack exchange,提问作者c136
相关产品推荐
相关产品推荐

