リンカー入力としての .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 以降ではサポートされなくなったためです。

コマンド ラインからリンカーを呼び出す方法については、「リンカーのコマンド ライン構文」および「コマンド ラインから 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++ コードでは、対応する trycatch ブロックが非 System 例外に対して呼び出されます。 ただし、既定では、非 System 例外は、CLR によって 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

関連項目