用作链接器输入的 .netmodule 文件
更新:2007 年 11 月
link.exe 现在可将 MSIL .obj 和 .netmodules 作为输入接受。链接器生成的输出文件将是一个程序集或 .netmodule,它们没有任何输入到链接器的 .obj 或 .netmodules 上的运行时依赖项。
.netmodules 由 Visual C++ 编译器通过 /LN(创建 MSIL 模块)或由链接器通过 /NOASSEMBLY(创建 MSIL 模块)创建。.objs 始终在 Visual C++ 编译中创建。对于其他 Visual Studio 编译器,请使用 /target:module 编译器选项。
在大多数情况下,除非通过 /clr(公共语言运行库编译)创建 .netmodule,否则需要将 .obj 文件从创建 .netmodule 的 Visual C++ 编译传递到链接器。用作链接器输入的 MSIL .netmodules 必须是纯 MSIL,可通过使用 /clr:safe 由 Visual C++ 编译器生成。默认情况下,其他 Visual Studio 编译器均生成纯 MSIL 模块。
有关如何从命令行调用链接器的信息,请参见链接器命令行语法和为命令行生成设置路径和环境变量。
将 .netmodule 或 .dll 文件传递到由 Visual C++ 编译器使用 /clr 或 /clr:pure 编译的链接器可能导致链接器错误。有关更多信息,请参见选择 .netmodule 输入文件的格式。
链接器接受本机 .obj 文件以及使用 /clr、/clr:pure 或 /clr:safe 编译的 MSIL .obj 文件。在相同版本中传递混合 .obj 时,默认情况下,得到的输出文件的可验证性等于输入模块的最低级别可验证性。例如,如果向链接器传递安全的纯 .obj,则输出文件将为纯 .obj。需要时,可通过 /CLRIMAGETYPE(指定 CLR 映像的类型)指定较低级别的可验证性。
如果当前的应用程序由两个或更多的程序集组成,并且您希望该应用程序包含在一个程序集中,则必须对程序集进行重新编译,然后链接 .obj 或 .netmodule 以便生成单个程序集。
创建可执行映像时,必须使用 /ENTRY(入口点符号)指定入口点。
与 MSIL .obj 或 .netmodule 文件链接时,应使用 /LTCG(链接时代码生成),否则当链接器遇到 MSIL .obj 或 .netmodule 时,将通过 /LTCG 重新启动链接。
MSIL .obj 或 .netmodule 文件也可以传递到 cl.exe。
MSIL .obj 或 .netmodule 输入文件不能具有嵌入资源。在其他 Visual Studio 编译器中使用 /ASSEMBLYRESOURCE(嵌入托管资源)链接器选项或 /resource 编译器选项将资源嵌入到输出文件(模块或程序集)中。
当执行 MSIL 链接时,如果未同时指定 /LTCG(链接时代码生成),则将出现一则信息性消息,报告正在重新启动链接。此消息可忽略,但要通过 MSIL 链接提高链接器性能,请显式指定 /LTCG。
示例
在 C++ 代码中,将针对非系统异常调用对应 try 的 catch 块。但是,默认情况下,CLR 将用 RuntimeWrappedException 包装非系统异常。如果程序集是从 Visual C++ 和非 Visual C++ 模块创建的,而且您希望在 try 块引发非系统异常时,从 C++ 代码中相应的 try 子句调用 catch 块,则必须将
[assembly:System::Runtime::CompilerServices::RuntimeCompatibility(WrapNonExceptionThrows=false)] 属性添加到非 C++ 模块的源代码中。
// MSIL_linking.cpp
// compile with: /c /clr
value struct V {};
ref struct MCPP {
static void Test() {
try {
throw (gcnew V);
}
catch (V ^) {
System::Console::WriteLine("caught non System exception in C++ source code file");
}
}
};
/*
int main() {
MCPP::Test();
}
*/
通过更改 WrapNonExceptionThrows 属性的布尔值,可以修改 Visual C++ 代码的功能以捕获非系统异常。
// MSIL_linking_2.cs
// compile with: /target:module /addmodule:MSIL_linking.obj
// post-build command: link /LTCG MSIL_linking.obj MSIL_linking_2.netmodule /entry:MLinkTest.Main /out:MSIL_linking_2.exe /subsystem:console
using System.Runtime.CompilerServices;
// enable non System exceptions
[assembly:RuntimeCompatibility(WrapNonExceptionThrows=false)]
class MLinkTest {
public static void Main() {
try {
MCPP.Test();
}
catch (RuntimeWrappedException) {
System.Console.WriteLine("caught a wrapped exception in C#");
}
}
}
caught non System exception in C++ source code file