リンカー入力としての .netmodule ファイル
link.exe では、MSIL の .obj
ファイルと .netmodule
ファイルを入力として受け取ります。 リンカーによって生成される出力ファイルは、リンカーに入力された .obj
ファイルまたは .netmodule
ファイルのいずれにも実行時の依存関係がないアセンブリまたは .netmodule
ファイルです。
解説
.netmodule
を作成するには、MSVC コンパイラで /LN (MSIL モジュールの作成) を使用するか、リンカーで /NOASSEMBLY (MSIL モードの作成) を使用します。 .obj
ファイルは常に C++ コンパイルで作成されます。 他の Visual Studio コンパイラの場合は、/target:module コンパイラ オプションを使用します。
リンカーには、.netmodule
を作成した C++ コンパイルからの .obj
ファイルを渡す必要があります。 .netmodule
で渡す方法はサポートされなくなりました。/clr:pure および /clr:safe コンパイラ オプションが Visual Studio 2015 では非推奨とされており、Visual Studio 2017 以降ではサポートされなくなったためです。
コマンド ラインからリンカーを呼び出す方法については、「Linker コマンド ライン構文」を参照してくださいコマンド ラインから MSVC ツールセットを使用する。
/clr を指定して MSVC コンパイラでコンパイルされたリンカーに .netmodule
ファイルまたは .dll
ファイルを渡すと、リンカー エラーが発生する可能性があります。 詳細については、「.netmodule入力ファイルの形式の選択」を参照してください。
リンカーは、ネイティブの .obj
ファイルだけではなく、/clr を指定してコンパイルされた MSIL の .obj
ファイルも受け入れます。 同じビルドに混在する .obj
ファイルを渡すことができます。 結果の出力ファイルの既定の検証可能性は、入力モジュールの最も低い検証可能性と同じです。
2 つ以上のアセンブリで構成されるアプリケーションを、1 つのアセンブリに含まれるように変更できます。 アセンブリのソースを再コンパイルしてから、.obj
ファイルまたは .netmodule
ファイルをリンクして 1 つのアセンブリを生成します。
実行可能イメージを作成するときに、/ENTRY (エントリポイント シンボル) を使用してエントリ ポイントを指定します。
MSIL の .obj
ファイルまたは .netmodule
ファイルとリンクする場合は /LTCG (リンク時コード生成) を使用します。それ以外の場合、リンカーで MSIL の .obj
または .netmodule
が検出されると、/LTCG を使用してリンクが再起動されます。 リンクを再起動することを示す情報メッセージが表示されます。 このメッセージは無視してもかまいませんが、リンカーのパフォーマンスを高めるには、明示的に /LTCG を指定してください。
MSIL の .obj
ファイルまたは .netmodule
ファイルも cl.exe に渡すことができます。
入力 MSIL の .obj
ファイルまたは .netmodule
ファイルに埋め込みリソースを含めることはできません。 /ASSEMBLYRESOURCE (管理対象リソースの埋め込み) リンカー オプションを使用して、リソースを出力モジュールまたはアセンブリ ファイルに埋め込みます。 または、他の Visual Studio コンパイラの /resource コンパイラ オプションを使用します。
例
C++ コードでは、対応する try
の catch
ブロックが非 System
例外に対して呼び出されます。 ただし、既定では、 CLR はSystem
以外の例外を RuntimeWrappedExceptionでラップします。 アセンブリが C++ および C++ 以外のモジュールから作成されており、try
ブロックから非 System
例外がスローされたときに C++ コード内の catch
ブロックを対応する try
句から呼び出すようにする場合、C++ 以外のモジュールのソース コードに [assembly:System::Runtime::CompilerServices::RuntimeCompatibility(WrapNonExceptionThrows=false)]
属性を追加する必要があります。
// 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
属性の Boolean
値を変更することで、C++ コードの機能が非 System
例外をキャッチするように変更されます。
// 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