C++嵌入Mono调用MSBuild编译C#程序时遇System.Runtime加载失败
问题描述
在C++中嵌入C# Mono运行时,使用MSBuild编译(编译过程正常),预期控制台输出Bark!!!,但实际触发未处理异常及断言错误,核心提示为无法加载运行时关键类型Main.Program,根源是无法加载程序集System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a或其依赖项。
环境与已完成排查:
- 安装x86版本Mono至
C:\Program Files (x86)\Mono,构建配置为x86 Debug - 使用MSBuild编译(xbuild已弃用;通过msc编译可正常运行,但需手动处理NuGet包,MSBuild更便捷)
- 已完成排查步骤:
- 确认Mono的lib文件夹存在System.Runtime程序集
- 验证
mono_set_dirs路径设置正确 - 将System.Runtime从4.3.1降级至4.0.0,问题未解决
需求:
- 解决上述程序集加载错误
- 若MSBuild与Mono存在兼容问题,说明为msc编译添加NuGet包的方法
解决方法
一、修复MSBuild下Mono加载System.Runtime的问题
添加程序集绑定重定向
在C#项目的App.config中添加绑定重定向配置,将高版本System.Runtime映射到Mono兼容的版本:<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>确保该配置文件被MSBuild复制到输出目录(可在.csproj中设置
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>)。强制生成Mono兼容的程序集
修改C#项目的.csproj文件,添加以下属性,强制编译为.NET Framework 4.7.2兼容版本,避免引入.NET Core/.NET 6的依赖:<PropertyGroup> <TargetFramework>net472</TargetFramework> <LangVersion>7.3</LangVersion> <DisableImplicitFrameworkReferences>false</DisableImplicitFrameworkReferences> </PropertyGroup>同时移除所有针对.NET Core/.NET 5+的NuGet包引用,仅保留.NET Framework兼容的包。
手动添加程序集搜索路径
在C++代码中,调用mono_add_assembly_search_path添加Mono的官方程序集路径,以及MSBuild输出目录中NuGet包的存放路径:// 添加Mono的.NET Framework兼容程序集路径 mono_add_assembly_search_path("C:\\Program Files (x86)\\Mono\\lib\\mono\\4.7.2-api"); // 添加NuGet包中System.Runtime的路径 mono_add_assembly_search_path("你的C#项目输出目录\\packages\\System.Runtime.4.0.0\\lib\\net46");
二、为msc编译添加NuGet包的方法
若MSBuild与Mono的兼容问题无法解决,可通过以下步骤为msc(Mono C#编译器)配置NuGet包:
- 下载NuGet包
使用NuGet CLI命令下载指定版本的包到本地目录:nuget install System.Runtime -Version 4.0.0 -OutputDirectory packages - 编译时引用程序集
调用msc编译C#代码时,通过-r参数指定NuGet包中的程序集路径:mcs /target:library /r:packages\System.Runtime.4.0.0\lib\net46\System.Runtime.dll Program.cs - 封装批处理脚本简化操作
将下载和编译命令写入批处理脚本,避免重复输入:@echo off nuget install System.Runtime -Version 4.0.0 -OutputDirectory packages mcs /target:library /r:packages\System.Runtime.4.0.0\lib\net46\System.Runtime.dll Program.cs
内容的提问来源于stack exchange,提问作者S.T.A.L.K.E.R

