9

この質問によると、C++/CLI を使用してマネージド コードとアンマネージド コードをシームレスに組み合わせることが可能です。よくわかりません-管理されたものと管理されていないものの間にマーシャリングがあるべきではありませんか?

たとえば、発行されたヘッダーを持つネイティブ C++ .dll としてコンパイルされる InnerLibrary と、InnerLibrary からコードを呼び出す C++/CLI OuterLibrary があります。マーシャリングはありますか?誰がそれを実装し、どのくらいの費用がかかりますか?

4

6 に答える 6

6

これは、C++ Interop と呼ばれる C++/CLI コンパイラに組み込まれている機能です。あなたが考えるかもしれない黒魔術がはるかに少ないです。JIT コンパイラは、C++ コンパイラが生成するのとまったく同じ種類のマシン コードを生成します。すべての .NET 値型は C++ で直接同等であるため、変換は必要ありません。参照型は自動的に処理されないため、自分で処理する必要があります。通常、pin_ptr<>。

実際に行うことは、マネージ スタック フレームからアンマネージ スタック フレームへの移行を処理するコードを挿入することだけです。そのコードは、ガベージ コレクタによって認識される特別な「Cookie」をスタックに置きます。これにより、管理されていないフレームに取り込まれ、管理されていないポインターをオブジェクト参照として誤認するのを防ぎます。そのコードにはそれほど多くはありません。リリース ビルドで約 5 ナノ秒かかります。ギブ オア テイクです。

于 2010-08-16T12:05:53.693 に答える
3

マーシャリングは、管理されていないデータまたは呼び出しを管理された世界に持ち込むプロセスです。いわば、2つの間の翻訳を行うだけです。

C++/CLI を使用すると、組み合わせることができます。つまり、*.h ファイルを使用し、従来の C++ コードを使用してライブラリを直接使用すると、管理されず、マーシャリングも行われません。BCL クラスまたは独自のマネージ コードを使用してそのデータにアクセスする場合、手動でマーシャリング レイヤーを追加しますが、それは必要な場合のみです。つまり、aLPTSTRを管理文字列として使用するには、管理文字列に変換する必要があります。C++/CLI を使用すると、この手順をスキップして従来の C++ コードに固執し、安全でチェック済みのマネージド コードを使用しないことを犠牲にして、より高速でより寛大なコードを作成できます。

于 2010-08-16T11:07:02.417 に答える
3

C++/CLI は安全でないコードを直接呼び出して発行できるため、マーシャリングは必要ありません。Reflector の C++/CLI コードをいくつか見てみましょう。これは C# とは大きく異なります。

これは、C# では実行できないことであり (少なくとも、unsafeキーワードといくつかのポインター ハックがなければできません)、純粋モードの C++/CLI では実行できないことでもあります (C# と同じ理由で)。

.NET アンセーフ コードは、アンマネージ関数を直接呼び出すことができます。この機能は、C++/CLI 以外では便利に利用できないというだけです。

于 2010-08-16T10:58:29.970 に答える
2

関与するマーシャリングがありますが、あなた (つまり、プログラマー) はそれを明示的に行う必要があります。

System.StringC++CLI OuterLibrary 呼び出しに/を取る関数があるSystem::String^場合、C++ 型システムでは、. を取る InnerLibrary 関数に渡す前に型変換を実行する必要がありますconst char*。自分で変換を行う必要があります - これがマーシャリングです。

Microsoft はC++ サポート ライブラリと呼ばれるものを出荷しています。これは、C++ <-> C++CLI の相互作用に役立つ機能を提供します。

于 2010-08-16T11:15:19.697 に答える
0

関連するデータ型によって異なります。

int、などの組み込み型double( は修飾されstringません) は、ネイティブ コードとマネージ コードの両方で同じ表現を持ち、マーシャリングは必要ありません。組み込み型の配列も同じように配置されます (メタデータ .NET ストアを無視すると、配列の内容とは別になります)。

すべてのメンバーが組み込み型である明示的なレイアウト属性を使用する値型も、メモリ レイアウトと互換性があります。

データがマネージド ヒープ上のオブジェクト内に格納されている場合は、固定が必要になることがあります (これはすべての配列に当てはまります)。

一方、クラス型は前後に変換/翻訳する必要があります。

于 2010-08-16T11:09:31.140 に答える
0

ここには 2 つのポイントがあります。

1) マネージド/アンマネージド コード移行: すべての移行には固定コストがあります。C++/CLI コードが 1 つのアセンブリにコンパイルされると、コンパイラは、可能であればすべてのコードを管理して、そのような遷移を最小限に抑えようとします。外部アンマネージ DLL が C++/CLI コードから呼び出される場合、そのような最適化は不可能です。したがって、少なくとも時間が重要なセクションでは、このような遷移を最小限に抑えることをお勧めします。詳細については、こちらを参照してください: http://msdn.microsoft.com/en-us/magazine/dd315414.aspx、Interop Boundary のパフォーマンスと場所

2) パラメータのマーシャリング。これは、パラメーターのタイプによって異なります。int のような単純な型など、一部のパラメーターはマーシャリングする必要はありません。文字列はマーシャリングする必要があります。ポインターの固定などのいくつかのトリックにより、単純型配列のマーシャリングを防ぐことができます。

于 2010-08-16T11:17:59.370 に答える