【发布时间】:2011-10-05 11:03:36
【问题描述】:
我正在尝试使用 /clr:pure 和 /clrimagetype:pure 标志从 C++/CLI 项目创建纯 MSIL 程序集,但是,输出程序集专门针对 x86。
我是否遗漏了任何可能阻止我的项目仅编译为 MSIL 的内容?
【问题讨论】:
标签: visual-c++ c++-cli clr
我正在尝试使用 /clr:pure 和 /clrimagetype:pure 标志从 C++/CLI 项目创建纯 MSIL 程序集,但是,输出程序集专门针对 x86。
我是否遗漏了任何可能阻止我的项目仅编译为 MSIL 的内容?
【问题讨论】:
标签: visual-c++ c++-cli clr
如果您使用的是 Visual Studio,您应该可以在 Linker -> Advanced settings 下设置 Target Machine 项目属性。
如果您正在寻找将您的 C++/CLI 项目编译为“Any CPU”,那么您需要在 /clr:safe 和 /clrimagetype:safe 中进行编译。有关详细信息,请参阅以下链接:
http://bytes.com/topic/net/answers/660475-any-cpu-build-c-cli
【讨论】:
您可以使用 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 Image Type 设置为 Force Pure IL Image /CLRIMAGETYPE:PURE,但其中一些明显的设置不适用,因为 32BIT+ 标志仍由PE32 标头中的链接器。corflags 步骤。最好的方法是退出 Visual Studio 并使用文本编辑器编辑 vcxproj 文件。在文件底部,添加:
目标>
这会运行corflags 工具来关闭 DLL 中的 32BIT 标志。确保corflags.exe 工具在您的路径中可用。#pragma warning(disable:4483)
void __clrcall __identifier(".cctor")() { }
就是这样,您现在可以构建 AnyCPU dll;由于“纯”设置,它是纯MSIL,并且由于corflags 调整,它将加载为x64 或x86。您可以在运行时避免使用任何不兼容的功能,例如互操作。然而——这是与仅仅使用/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 在这里仍然为您做的一件好事是默默地创建一个托管值类型(结构)来覆盖您的每个本机静态,以便 IL 代码可以直接使用 IL 获取它们指针,从而保持程序集 /pure.
[编辑:更正了关于 AnyCPU 程序集中“本机”指针的错误陈述] [编辑:澄清:纯汇编中的“不安全”C#代码通过IL指令(例如ldloca等)使用托管指针]
【讨论】: