You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:39:15