.NETMODULE-файлы в качестве входных файлов компоновщика
Программа link.exe теперь принимает в качестве входных данных OBJ- и NETMODULE-файлы MSIL. Файл вывода, создаваемый компоновщиком, будет являться сборкой или NETMODULE- файлом, время выполнения которых не зависит от OBJ- или NETMODULE- файлов для компоновщика.
. NETMODULE-файлы создаются с использованием компилятора Visual C++ с параметром /LN (создание модуля MSIL) или с использованием компоновщика с параметром /NOASSEMBLY (создать модуль MSIL). OBJS-файлы всегда создаются при компиляции в Visual C++. Для других компиляторов Visual Studio используется параметр компилятора /target:module.
В большинстве случаев нужно будет передать в компоновщик OBJ-файл из компиляции Visual C++, создавшей NETMODULE- файл, если NETMODULE- файл не был создан с помощью /clr (компиляция CLR). NETMODULE- файлы MSIL, используемые как входные файлы компоновщика, должны содержать чистый код MSIL, который может быть получен с помощью компилятора Visual C++ с указанием параметра /clr:safe. Другие компиляторы Visual Studio создают модули MSIL по умолчанию.
Сведения о запуске компоновщика из командной строки см. в разделах Синтаксис командной строки компоновщика и Установка переменных пути и среды при построении из командной строки.
Передача компоновщику NETMODULE- или DLL-файла, скомпилированного с помощью компилятора Visual C++ с указанием параметров /clr или /clr:pure, может привести к ошибке компоновщика. Дополнительные сведения см. в разделе Выбор формата входных файлов netmodule.
Компоновщик принимает машинные OBJ-файлы, а также OBJ-файлы на языке MSIL, скомпилированные с использованием параметров /clr, /clr:pure или /clr:safe. При передаче смешанных OBJ-файлов в одном построении проверяемость результирующих выходных файлов будет равна по умолчанию минимальному уровню проверяемости входных модулей. Например, если передать компоновщику безопасный и чистый OBJ-файл, то файл вывода будет чистым. Параметр /CLRIMAGETYPE (указание типа образа среды CLR) позволяет указать более низкий уровень проверяемости, если это необходимо.
При наличии приложения, состоящего из двух или нескольких сборок, которое необходимо объединить в одну сборку, следует перекомпилировать сборку и затем произвести компоновку OBJ-файлов или NETMODULE- файлов, чтобы получить единую сборку.
При создании исполняемого образа необходимо задать точку входа с помощью параметра /ENTRY (символ точки входа).
При работе с OBJ- и NETMODULE- фалами MSIL следует использовать параметр Параметр /LTCG (создание кода во время компоновки); в противном случае, если компоновщик обнаружит OBJ- или NETMODULE- файл MSIL, он перезапустит компоновку с параметром /LTCG.
OBJ- и NETMODULE- файлы MSIL также могут быть переданы программе cl.exe.
Входные OBJ- и NETMODULE- файлы MSIL не могут иметь внедренных ресурсов. Ресурс внедряется в выходной файл (модуль или сборку) с помощью параметра компилятора /ASSEMBLYRESOURCE (внедрение управляемого ресурса) или параметра компилятора /resource для других компиляторов Visual Studio.
При выполнении компоновки MSIL, если не указать также параметр Параметр /LTCG (создание кода во время компоновки), будет выведено информационное сообщение, уведомляющее о перезапуске компоновки. Это сообщение можно проигнорировать, но в целях повышения производительности компоновки MSIL следует явно задать параметр /LTCG.
Пример
В коде на языке C++ блок catch, связанный с соответствующим try, будет вызван при возникновении несистемного исключения. Однако по умолчанию среда CLR упаковывает несистемные исключения с помощью RuntimeWrappedException. При создании сборки из модулей Visual C++ и не-Visual C++ и необходимости вызова блока catch в коде C++ из соответствующей конструкции try при создании блоком try несистемного исключения следует добавить атрибут
[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#");
}
}
}