我正在尝试使用/ clr:pure和/ clrimagetype:pure flags从C ++ / CLI项目创建纯MSIL程序集,但是,输出程序集专门针对x86。
我是否遗漏了可能阻止我的项目仅编译为MSIL的任何内容?
答案 0 :(得分:13)
您可以使用 C ++ / CLI 创建 AnyCPU dll,但在最简单的情况下,您将无法使用MFC,ATL或CRT。但是,如果您只想在C ++ / CLI中编写纯托管.NET代码,包括托管指针(/clr:safe
不允许),并获得更精细的C ++ / CLI编译器代码优化,请继续阅读:
/clr:pure
。这是在Visual Studio 2010中的Configuration Properties
页面上。Omit Default Library Name
设置为Yes /Zl
Incremental Linking
和Link Library Dependencies
Not Set
,将CLR图像类型设置为Force Pure IL Image /CLRIMAGETYPE:PURE
,但是这些显着设置中的一些不受尊重,因为32BIT +标记是仍然由PE32头中的链接器设置。corflags
步骤。执行此操作的最佳方法是退出Visual Studio并使用文本编辑器编辑vcxproj文件。在文件的底部,添加:<!-- at the bottom of the file... --> <Target Name="AfterBuild"> <Exec Command="corflags $(TargetPath) /32BIT-" /> </Target> </Project>这将运行
corflags
工具以关闭DLL中的32BIT标志。确保您的路径中有corflags.exe
工具。#pragma warning(disable:4483) void __clrcall __identifier(".cctor")() { }
就是这样,你现在可以构建 AnyCPU dll;由于“纯”设置,它是纯MSIL
,并且由于corflags
调整,它将加载为 x64 或 x86 。您可以在运行时避免使用任何不兼容的功能,例如Interop。但是 - 这是与使用/clr:safe
模式(也产生AnyCPU库)的差别 - 你可以使用不安全的托管指针来访问托管值类型。
static int my_arr[] = { 1, 2, 3 };
链接器会对此效果发出警告warning LNK4210: .CRTMA section exists; there may be unhandled static initializers or terminators
。但是,您可以声明它们,自己初始化它们,然后使用它们 - 也就是说,获取它们的地址 - 并从托管代码中读取/写入它们(如果要将这样的数组声明为const
,那么你必须为初始值设定项提供空大括号{ }
并将指针强加到volatile
以初始化它。):
static int my_arr[3];
具有讽刺意味的是,初始化这些本机静态资源或表的一种方法是在模块构造函数或类静态构造函数中从托管变量或资源中复制它们。
为什么要打扰原生静电?因为它们可以快速访问而无需固定。 C ++ / CLI 这里的一件好事仍然是默默地创建一个托管值类型(struct)来覆盖每个本机静态,以便IL代码可以直接用IL获取它们指针,从而保持程序集 / pure 。
[编辑:纠正了关于AnyCPU程序集中“本机”指针的错误陈述] [编辑:澄清:纯粹程序集中的'不安全'C#代码通过IL指令使用托管指针,例如ldloca等。]
答案 1 :(得分:4)
如果您使用的是Visual Studio,则应该能够在Linker下设置Target Machine项目属性 - &gt;高级设置。
如果您要查找的是将C ++ / CLI项目编译为“任何CPU”,则需要在/ clr:safe和/ clrimagetype:safe中编译。有关更多信息,请参阅以下链接:
http://bytes.com/topic/net/answers/660475-any-cpu-build-c-cli