C++/C#解决方案中没有的任何CPU

Fra*_*ijk 16 c# c++ managed anycpu

我有一个包含C#和托管C++项目的解决方案.它在解决方案平台x64和x86中编译.由于它是托管C++,我想创建一个'Any CPU'解决方案并摆脱旧的解决方案.

我将C++项目链接器设置更改为x64和x86的强制安全IL映像.

接下来,使用Configuration Manager,我创建了一个名为"Any CPU"的新解决方案平台.接下来我添加了一个名为"Any CPU"的项目平台.

我继续将所有C#项目设置为"任何CPU",但对于C++我不能这样做.项目平台'Any CPU'不在下拉列表中,也没有选项'New ...'.

VS是关于它的,所以我保持它就像它并开始构建.令我惊讶的是,结果DLL(来自C++项目)是MSIL,即使C++的平台是x64.编译x32时也是如此,生成的DLL在MSIL中.

是什么赋予了?为什么我不能将C++项目设置为"任何CPU"?

Pet*_*iho 13

据我所知,您不能在Visual Studio中为C++/CLI项目创建"AnyCPU"项目类型.但是,您可以配置C++/CLI项目(在"Win32"项目类型下),以便在没有目标平台的情况下编译为纯粹,安全的MSIL.这样做将允许您的C++/CLI DLL程序集与"AnyCPU"C#项目一起使用.即它实际上是"AnyCPU",即使它不是它在Configuration Manager中的实际名称.

在"C/C++"项目设置中:

  • 公共语言运行时支持: Safe MSIL Common Language RunTime Support (/clr:safe)

在"链接器"项目设置中:

  • CLR图像类型:只是确保未将其明确设置为IJWPURE

笔记:

  • 通过使用"安全"项目类型,将忽略一些似乎影响平台类型的编译器和链接器选项.也就是说,您不必经历并将所有内容设置为非特定平台类型.就在上面.但是如果它让你感觉更好,你可以将其他选项设置为合适的选项.:)
  • "安全"将阻止指针的使用.如果这是一个重要的问题,显然可能会做一个更复杂的过程.请参阅从C++/CLI项目创建纯MSIL程序集?详情.
  • 不要忘记,默认情况下,Visual Studio将创建C#项目,即使它们是"AnyCPU",即使它们是在64位操作系统上执行,也会以32位进程启动.如果依赖项是x86而不是预期的纯/安全MSIL,这可以隐藏平台不匹配问题.只需注意一下(您可以通过取消选中C#项目的"Build"项目属性页面中的"Prefer 32-bit"选项来控制它).


Kev*_*all 5

为了让C#dll使用C ++功能,C ++项目必须同时生成x86和x64版本的dll。从使用AnyCPU设置编译的C#dll中仅引用x86或x64 dll是不可能的。

使AnyCPU dll与C ++ dll一起播放的技巧是在运行时确保程序集无法加载C ++ dll,然后订阅AppDomain AssemblyResolve事件。当程序集尝试加载dll并失败时,您的代码就有机会确定需要加载哪个dll。

订阅事件看起来像这样:

System.AppDomain.CurrentDomain.AssemblyResolve += Resolver;
Run Code Online (Sandbox Code Playgroud)

事件处理程序看起来像这样:

System.Reflection.Assembly Resolver(object sender, System.ResolveEventArgs args)
{
     string assembly_dll = new AssemblyName(args.Name).Name + ".dll";
     string assembly_directory = "Parent directory of the C++ dlls";

     Assembly assembly = null;
     if(Environment.Is64BitProcess)
     {
            assembly = Assembly.LoadFile(assembly_directory + @"\x64\" + assembly_dll);
     }
     else
     {
            assembly = Assembly.LoadFile(assembly_directory + @"\x86\" + assembly_dll);
     }
     return assembly;
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个简单的项目,演示了如何从AnyCPU dll访问C ++功能。

https://github.com/kevin-marshall/Managed.AnyCPU