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

制作供C++程序调用的C# DLL时遇程序集加载异常求助

解决CLR包装器调用C# DLL时的System.IO.FileNotFoundException问题

问题背景

编写C#类库SimpleMathLib编译为DLL,通过CLR C静态库做包装器,再用C控制台程序调用。无论使用链接器还是手动加载DLL,运行时均抛出System.IO.FileNotFoundException,提示找不到netstandard等程序集。已安装对应.NET Runtime和SDK,更换目标框架版本仅改变缺失的程序集名称/版本,问题依旧。

解决方案

1. 同步程序集输出目录

  • 将SimpleMathLib.dll及其依赖的所有.NET程序集(如netstandard.dll、System.Runtime.dll等)复制到C++控制台程序的Debug/Release输出目录。
  • 若C#类库目标为.NET Core/.NET 5+,可通过dotnet publish打包所有依赖:
    dotnet publish SimpleMathLib.csproj -c Release -r win-x64 --self-contained false
    
    将publish目录下的所有文件复制到C++程序输出目录。

2. 匹配CLR目标框架版本

  • 右键C++包装器项目 → 属性 → 常规 → 确保公共语言运行时支持版本与C#类库目标框架一致:
    • C#用.NET Framework 4.x时,C++选对应.NET Framework 4.x;
    • C#用.NET 6/7/8时,C++选对应.NET Core版本(需安装Visual Studio的.NET Core开发工具)。
  • 同步C++控制台项目与包装器项目的运行库设置(如均为Multi-threaded Debug DLL (/MDd))。

3. 配置程序集绑定重定向(.NET Framework场景)

  • 在C++控制台程序输出目录创建[程序名].exe.config文件,添加绑定重定向规则:
    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="netstandard" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-2.0.3.0" newVersion="2.0.3.0" />
            <codeBase version="2.0.3.0" href="netstandard.dll" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    
    替换publicKeyToken和版本号为实际缺失程序集的信息。

4. 手动加载程序集的正确方式

  • 若手动加载C# DLL,需先设置程序集解析路径:
    #include <mscoree.h>
    #pragma comment(lib, "mscoree.lib")
    
    void SetAssemblySearchPath(const wchar_t* path) {
        ICLRMetaHost* pMetaHost = nullptr;
        ICLRRuntimeInfo* pRuntimeInfo = nullptr;
        ICLRRuntimeHost* pRuntimeHost = nullptr;
    
        if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost) == S_OK) {
            pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);
            pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pRuntimeHost);
            pRuntimeHost->Start();
            
            ICLRControl* pControl = nullptr;
            pRuntimeHost->GetCLRControl(&pControl);
            ICLRAssemblyIdentityManager* pIdentityManager = nullptr;
            pControl->GetCLRManager(IID_ICLRAssemblyIdentityManager, (LPVOID*)&pIdentityManager);
            ICLRAssemblyReferenceList* pRefList = nullptr;
            pIdentityManager->CreateAssemblyReferenceListFromPath(path, &pRefList);
            pControl->SetAppDomainManagerType(L"", L"", pRefList);
            
            pRefList->Release();
            pIdentityManager->Release();
            pControl->Release();
            pRuntimeHost->Release();
            pRuntimeInfo->Release();
            pMetaHost->Release();
        }
    }
    
    在加载C# DLL前调用SetAssemblySearchPath传入C# DLL所在目录。

5. 配置项目部署规则

  • 右键C++控制台项目 → 属性 → 部署 → 将C# DLL及其依赖项添加为附加文件,设置复制到输出目录为始终复制。

内容的提问来源于stack exchange,提问作者Apache81

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:55:04