1

CLR がネイティブ コードを「管理」し、そのネイティブ コード (c++ 関数) を c# から直接呼び出すことができるようにコンパイルされているプロジェクト (SharpDX など) がたくさんあることがわかりました。

私はこれがどのように機能するかを理解しようとしています..そして、そこにいる誰かが知っていればいいでしょう.

これまで見てきたことは、C# プロジェクトの参照を、他の C# ライブラリと同じように (リフレクションを必要とせずに) 「CLR 互換」C++ ライブラリに追加し、「myCppLibrary を使用して」のように追加してから、利用可能なメソッドを呼び出します。

追加したばかりの参照で使用できる関数を確認したところ、C++ ライブラリのヘッダー (.h) ファイルで PUBLIC として宣言されたすべての関数に c# からアクセスできるようです。コンパイラ。

したがって、実際に何が起こっているかは次のとおりです。

C++ ライブラリのヘッダー (.h) ファイルでパブリック メソッド/変数を宣言しています。ライブラリの [プロパティ] タブで CLR 管理が利用できることを確認してコンパイルします。(私は Visual Studio 2012 を使用しています) コンパイラは、すべてのヘッダー ファイル (.h) に対して c# クラスを生成し、その上にパブリック メソッド/プロパティを含めます。

しかし、私が理解していないのは、「myCppLibrary」からの GiveNumber() 関数を呼び出す方法です..その関数の実装はどこで実行されますか?

CLR は C++ ネイティブ コードと自動的に相互通信しますか、それとも実際に何が起こっているのでしょうか?

4

2 に答える 2

3

あなたが見ているものを正確に理解しているかどうかはわかりません。しかし、間違いの副作用が見られる可能性は高いです。C++/CLI コンパイラは、C++03 互換のネイティブ C++ コードを IL にコンパイルできます。IL とジッターはどちらも、これをサポートするのに十分柔軟です。そして、たとえば C# コンパイラによって生成された IL と同様に、この種の IL は実行時にマシン コードに変換され、まったく同じ方法で最適化されます。

ただし、これはマネージ コードにはなりません。このコードによって作成されたオブジェクトは、ネイティブ C++ コンパイラと同様に、アンマネージ メモリに割り当てられるネイティブ オブジェクトのままです。ガベージ コレクターはそれらを完全に無視します。

間違いは、そのコードを IL に変換できるようにすることです。C++ コード ジェネレーターが最適な最適化されたマシン コードを見つけるためにコンパイル時に費やす余分な時間を逃しています。ジッターも最適化されますが、時間の制約の下で動作する必要があるため、それほど良い仕事をすることはできません. そしてもちろん、実行時にジッティングのオーバーヘッドが発生します。

ネイティブの構造体とクラスは、アセンブリ メタデータに表示されます。ただし、これらは、C# プログラムからアクセスできるメンバーを持たない不透明な値の型にすぎません。このようなネイティブ クラスのメソッドを C# から直接呼び出すことはできません。使用可能にするには、C++/CLI プログラムでvalueまたはrefコンテキスト キーワードを使用して型を宣言する必要があります。ref classと同様に、C# クラスとまったく同等です。

したがって、通常の C++ コンパイラと同様に、ネイティブ コードをマシン コードにコンパイルすることが重要です。これを行うには、/clr を有効にせずに .cpp ソース ファイルをコンパイルします。または、そのようなコードを #pragma unmanaged と #pragma managed でラップし、コンパイラをマシン コードと IL 生成の間で切り替えます。C++/CLI から得られる付加価値は、pinvoke のように C# で行わなければならない手間をかけずに、ref クラスのメソッドがネイティブ コードを直接使用できることです。また、ネイティブ C++ クラスを使用することは、C# からはまったくできないことです。

于 2013-05-30T21:07:36.337 に答える
2

C++ で CLR を有効にすると、コンパイラは C++ コードをネイティブ コードではなく IL にコンパイルします。この場合、C++/CLIとして知られる C++は、さまざまな機能で拡張され、ガベージ コレクターを使用できるようになり、ガベージ コレクションされたメモリが固定されて動き回らないようにするかどうかを細かく制御できるようになります。

一般に、C++/CLI の記述は専門的な作業であり、C++ と C# の両方の知識が必要です (いくつかの微妙な違いや落とし穴があります)。一般に、ネイティブ コードとマネージ コードの間のインターフェイスに推奨されますが、ライブラリ全体を .net にするために使用できます。

于 2013-05-30T20:30:23.293 に答える