次の方法で共有


リンカー入力としての .netmodule ファイル

link.exe では、MSIL の .obj ファイルと .netmodule ファイルを入力として受け取ります。 リンカーによって生成される出力ファイルは、リンカーに入力された .netmodule ファイルまたは .obj ファイルのいずれにも実行時の依存関係がないアセンブリまたは .netmodule ファイルです。

解説

.netmodule を作成するには、MSVC コンパイラで /LN (MSIL モジュールの作成) を使用するか、リンカーで /NOASSEMBLY (MSIL モードの作成) を使用します。 .obj ファイルは常に C++ コンパイルで作成されます。 他の Visual Studio コンパイラの場合は、/target:module コンパイラ オプションを使用します。

リンカーには、.obj を作成した C++ コンパイルからの .netmodule ファイルを渡す必要があります。 .netmodule で渡す方法はサポートされなくなりました。/clr:pure および /clr:safe コンパイラ オプションが Visual Studio 2015 では非推奨とされており、Visual Studio 2017 以降ではサポートされなくなったためです。

コマンド ラインからリンカーを呼び出す方法については、「Linker コマンド ライン構文」を参照してくださいコマンド ラインから MSVC ツールセットを使用する

.dll を指定して MSVC コンパイラでコンパイルされたリンカーに clr ファイルまたは ファイルを渡すと、リンカー エラーが発生する可能性があります。 詳細については、「.netmodule入力ファイルの形式の選択」を参照してください。

リンカーは、ネイティブの .obj ファイルだけではなく、clr を指定してコンパイルされた MSIL の ファイルも受け入れます。 同じビルドに混在する .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++ コードでは、対応する catchtry ブロックが非 System 例外に対して呼び出されます。 ただし、既定では、CLR は非System 例外を RuntimeWrappedExceptionでラップします。 アセンブリが C++ および C++ 以外のモジュールから作成されており、catch ブロックから非 try 例外がスローされたときに C++ コード内の try ブロックを対応する System 句から呼び出すようにする場合、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();
}
*/

Boolean 属性の WrapNonExceptionThrows 値を変更することで、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

関連項目