/clr(公共语言运行库编译)
更新:2007 年 11 月
使应用程序和组件能够使用公共语言运行库 (CLR) 中的功能。
/clr[:options]
参数
options
以下一个或多个选项,以逗号分隔:/clr
为您的应用程序创建可由其他 CLR 应用程序使用的元数据,并允许您的应用程序使用其他 CLR 组件的元数据中的类型和数据。有关更多信息,请参见:
/clr:pure
生成仅包含 MSIL 的输出文件,其中不包含任何本机可执行代码,但是可以包含编译为 MSIL 的本机类型。有关更多信息,请参见纯代码和可验证代码。
/clr:safe
生成仅包含 MSIL(无本机可执行代码)且可验证的输出文件。/clr:safe 启用验证诊断 (PEVerify 工具 (Peverify.exe))。有关更多信息,请参见编写可验证为类型安全的代码。
/clr:oldSyntax
针对 C++ 语法(CLR 编程的原始 Visual C++ 语法)启用托管扩展。注意 在 Microsoft Visual C++ 2005 中,已否决 C++ 托管扩展语法。只有在维护使用 C++ 托管扩展的 Visual C++ 应用程序时,才应使用 /clr:oldSyntax。如果要开发新应用程序,请使用更新的语法;有关更多信息,请参见New C++ Language Features。
如果您拥有 C++ 应用程序的托管扩展,就可以开始停靠您的项目以使用新语法;有关更多信息,请参见 移植和升级程序。
/clr:noAssembly
noAssembly 选项指定不应将程序集清单插入到输出文件中。默认情况下,noAssembly 选项不起作用。注意 在 Visual C++ 2005 中,已否决 noAssembly 选项。应改用 /LN(创建 MSIL 模块)。有关更多信息,请参见Visual C++ 2005 中不推荐使用的编译器选项。
清单中不包含程序集元数据的托管程序称为“模块”。noAssembly 选项只可用于生成模块。如果使用 /c(编译但不链接) 和 /clr:noAssembly 进行编译,则应在链接器阶段指定 /NOASSEMBLY(创建 MSIL 模块) 选项以创建模块。
在 Visual C++ 2005 之前,/clr:noAssembly 暗示 /clr。但是,现在 /clr 还支持 /clr:oldSyntax,因此必须在指定 /clr:noAssembly 时指定一个 /clr 形式。例如,/clr:noAssembly /clr 使用新的 Visual C++ CLR 语法创建模块,而 /clr:noAssembly,oldSyntax 使用 C++ 托管扩展创建模块。
在 Visual C++ 2005 之前,/clr:noAssembly 需要 /LD。而现在 /LD 通过指定 /clr:noAssembly 来表示。
/clr:initialAppDomain
允许 Visual C++ 应用程序在公共语言运行库版本 1 中运行。如果使用 initialAppDomain,则可以参见知识库文章 Q309694 中讨论的一些问题。可以查找 MSDN Library 媒体中或 https://support.microsoft.com/default.aspx?ln=zh-cn 中的知识库文章。用 initialAppDomain 编译的应用程序决不应该由使用 ASP.NET 的应用程序使用。应升级到较新的运行库,以便用 C++ 执行 ASP.NET 任务。
备注
托管代码是可由公共语言运行库检查和管理的代码。托管代码可以访问托管对象。
另请参见 /clr 限制。
有关如何开发定义和使用托管类型的应用程序的信息,请参见 New C++ Language Features。
使用 /clr 编译的应用程序可能包含托管数据,也可能不包含托管数据。
若要允许在托管应用程序中进行调试,请参见 /ASSEMBLYDEBUG(添加 DebuggableAttribute)。
只有 CLR 类型将在垃圾回收堆中进行实例化。有关更多信息,请参见 Classes and Structs (Managed)。若要将函数编译为本机代码,请使用 unmanaged 杂注。有关更多信息,请参见 managed, unmanaged。
默认情况下,/clr 无效。当 /clr 生效时,/MD 也将生效(有关更多信息,请参见 /MD)。/MD 确保从标准头 (.h) 文件中选择运行库例程的动态链接的多线程版本。多线程处理是托管编程所必需的,其中一部分原因是 CLR 垃圾回收器将在辅助线程中运行终结器。
如果使用 /c 进行编译,则可以使用 /CLRIMAGETYPE(指定 CLR 映像的类型) 指定生成的输出文件的 CLR 类型(IJW 类型、安全类型或纯类型)。
/clr 暗指 /EHa,不允许其他 /EH 选项与 /clr 一起使用。有关更多信息,请参见 /EH(异常处理模型)。
有关如何确定文件的 CLR 映像类型的信息,请参见 /CLRHEADER。
必须使用同一个运行时库编译器选项(/MD 或 /LD)编译传递到给定链接器调用的所有模块。
使用 /ASSEMBLYRESOURCE(嵌入托管资源) 链接器选项在程序集中嵌入资源。/DELAYSIGN(为程序集进行部分签名)、/KEYCONTAINER(指定密钥容器以便为程序集签名) 和 /KEYFILE(指定密钥或密钥对以便为程序集签名) 链接器选项也可用于自定义程序集的创建方式。
使用 /clr 时,_MANAGED 符号被定义为 1。有关更多信息,请参见 Predefined Macros。
首先将初始化本机对象文件中的全局变量(如果可执行文件为 DLL,则在 DllMain 期间),然后将初始化托管部分中的全局变量(在运行任何托管代码之前)。#pragmainit_seg 仅影响托管和非托管类别中的初始化顺序。
使用 /clr:safe 进行编译与对诸如 C# 等语言使用 /platform:anycpu 进行编译很相似。
安全映像和纯映像
纯映像将使用 C 运行时库的 CLR 版本。但是,CRT 无法验证,因此使用 /clr:safe 进行编译时不能使用 CRT。有关更多信息,请参见 C Run-Time Libraries。
不能出现在纯映像中的本机代码的示例包括内联程序集、setjmp 或 longjmp。
纯映像或安全映像的每个入口点都被托管。使用 /clr 进行编译时,入口点是本机入口点。有关更多信息,请参见 __clrcall。
使用 /clr:safe 进行编译时,变量默认为 appdomain 范围的,而不能是基于每个进程的。使用 /clr:pure 时,appdomain 为默认值,但是可以使用 process 变量。
在 64 位操作系统中运行使用 /clr 或 /clr:pure 编译的 32 位 .exe 文件时,应用程序将在 WOW64 下运行,WOW64 允许在 64 位操作系统中由 32 位 CLR 运行 32 位应用程序。默认情况下,使用 /clr:safe 编译的 .exe 将在运行 64 位操作系统的计算机的 64 位 CLR 中运行(在 32 位操作系统中,同样的 .exe 在 32 位 CLR 中运行)。但是,安全应用程序可以加载 32 位组件。在这种情况下,当安全映像加载 32 位应用程序时,在操作系统的 64 位支持下运行的安全映像将会失败 (BadFormatException)。若要确保安全映像在 64 位操作系统中加载 32 位映像时继续运行,必须使用 /CLRIMAGETYPE(指定 CLR 映像的类型) 更改元数据 (.corflags),将其标记为在 WOW64 下运行。以下是示例命令行(替代您自己的输入符号):
cl /clr:safe t.cpp /link /clrimagetype:pure /entry:?main@@$$HYMHXZ /subsystem:console
有关获取修饰名的信息,请参见 使用列表查看修饰名。有关 64 位编程的更多信息,请参见 64 位编程(如何实现 - Visual C++)。
有关示例、演练及更多信息,请参见:
元数据和未命名类
未命名类将显示在名称形式如下的元数据中:$UnnamedClass$当前文件名的 crc$索引$,其中“索引”是未命名类在编译中的顺序号。例如,下列代码示例将在元数据中生成未命名类:
// clr_unnamed_class.cpp
// compile with: /clr /LD
class {} x;
使用 ildasm.exe 查看元数据。
在 Visual Studio 开发环境中设置此编译器选项
打开项目的“属性页”对话框。有关详细信息,请参见如何:打开项目属性页。
单击“配置属性”文件夹。
单击“常规”属性页。
修改“公共语言运行库支持”属性。
有关如何创建模块的信息,请参见 /NOASSEMBLY(创建 MSIL 模块)。
说明: 在项目的“属性页”对话框中启用 /clr 后,与 /clr 不兼容的编译器选项属性也将根据需要进行调整。例如,如果设置 /RTC,然后启用 /clr,/RTC 将被关闭。
另外,调试 /clr 应用程序时,“调试器类型”属性应设置为“混合”或“仅限托管”。有关更多信息,请参见 C++ 调试配置的项目设置。
以编程方式设置此编译器选项
- 请参见 CompileAsManaged。