我正在尝试使用/clr:pure和/clrimagetype:pure标志从C++/CLI项目创建纯MSIL程序集,但输出程序集明确针对x86目标。
我是否遗漏了任何可能阻止我的项目仅编译为MSIL的内容?
我正在尝试使用/clr:pure和/clrimagetype:pure标志从C++/CLI项目创建纯MSIL程序集,但输出程序集明确针对x86目标。
我是否遗漏了任何可能阻止我的项目仅编译为MSIL的内容?
/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文件。在该文件的底部添加:<!-- 在文件底部... --> <Target Name="AfterBuild"> <Exec Command="corflags $(TargetPath) /32BIT-" /> </Target> </Project>这将运行
corflags
工具以关闭DLL中的32BIT标志。确保corflags.exe
工具在您的路径中可用。#pragma warning(disable:4483) void __clrcall __identifier(".cctor")() { }
就这样,您现在可以构建AnyCPUDLL;它是纯MSIL
,因为使用了'pure'设置,而且由于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 等)的托管指针。]
http://bytes.com/topic/net/answers/660475-any-cpu-build-c-cli