2

アンマネージC++からC#ライブラリ実装を呼び出すためのオプションを理解しようとしています。

私の最上位モジュールは、管理されていないC ++ COM /ATLdllです。既存のマネージドC#dllの機能を統合したいと思います。私は持っており、両方のライブラリのソースを再コンパイルできます。

MSDNのこの概要やこのSOの質問などの記事を読んだことで、ネイティブC ++コードがC#ライブラリを呼び出すことができる「混合モード」dllを作成できる可能性があることを理解しています。

このアプローチについていくつか質問があります。

  1. これを設定するにはどうすればよいですか?既存のCOM/ATLプロジェクトのいくつかのプロパティを変更して、C#モジュールを使用できるようにすることはできますか?
  2. これらの混合モード呼び出しは、COM相互運用呼び出しとパフォーマンスがどのように異なりますか?モジュール間の変換やディープコピーを防ぐために使用できる一般的な文字列形式はありますか?
  3. このdllが混合モードで作成されている場合でも、COMクライアントによって同じ方法でインターフェイス/使用できますか、それとも混合モードに対応する必要がありますか?
  4. このCOMオブジェクトをロードするときに、CLRを含めるとかなりのオーバーヘッドが発生しますか?

私はWindows開発に不慣れなので、質問文の何かを明確にするか修正する必要がある場合はコメントしてください。

前もって感謝します。

4

2 に答える 2

4

これを設定するにはどうすればよいですか?既存のCOM/ATLプロジェクトのいくつかのプロパティを変更して、C#モジュールを使用できるようにすることはできますか?

そのプロジェクトを完全に制御しているので、そのような設定を変更することは問題ではありません。必要なのは/clr、このプロジェクトを有効にすることだけです(プロジェクトのプロパティで、[全般]ページを開き、[共通言語ランタイム]のサポートを探します)。これで、必要に応じて、プロジェクトでマネージドハンドル(^)およびその他のC ++/CLIビットを使用できます。プレーンC++で記述された既存のコードはすべて、引き続き機能するはずです(可能な限り、MSILにコンパイルされますが、セマンティクスは変更されません)。

これらの混合モード呼び出しは、COM相互運用呼び出しとパフォーマンスがどのように異なりますか?モジュール間の変換やディープコピーを防ぐために使用できる一般的な文字列形式はありますか?

混合モードの呼び出しは、より高速な呼び出し規約を使用し、COM相互運用機能のようにマーシャリングを行わないため、より高速になります(本質的に互換性のある型を使用するか、独自の明示的な変換を行います)。

一般的な文字列形式はありません。問題はSystem::String、バッファの割り当てと所有の両方が行われ、不変である必要があることです。したがって、自分でバッファを作成してからそれをラップしStringたり、を作成してStringからテキストを出力するためのバッファとして使用したりすることはできません。

このdllが混合モードで作成されている場合でも、COMクライアントによって同じ方法でインターフェイス/使用できますか、それとも混合モードに対応する必要がありますか?

同じようにインターフェイスできますが、ネイティブエントリポイントを介して入力された場合、CLRがすでにロードされていない限り、プロセスにCLRをロードしようとします。呼び出し元のクライアントが呼び出し前にCLRを既にロードしている場合(またはクライアント自体がマネージコードから呼び出されている場合)、すでにロードされているCLRを取得します。これは、コードに必要なCLRとは異なる場合があります(例:クライアント1.1がロードされている可能性があり、コードには2.0が必要です)。

このCOMオブジェクトをロードするときに、CLRを含めるとかなりのオーバーヘッドが発生しますか?

これは、オーバーヘッドによって何を定義するかによって異なります。コードサイズ?実行時のペナルティ?メモリーフットプリント?

いずれにせよ、CLRをロードするということは、すべてのGCおよびJIT機械を入手することを意味します。それらは安くはありません。とはいえ、最終的にマネージコードを呼び出す必要がある場合は、これを回避する方法はありません。これを行うには、CLRを何らかのプロセスにロードする必要がありますペナルティは、COM相互運用機能と混合モードC ++/CLIアセンブリの間で違いはありません。

于 2009-12-16T17:25:12.073 に答える
0

私はこのアプローチを積極的に使用したことがないので、たとえば文字列の問題などの詳細についてはあまり言えません。

ただし、VSウィザードにプロキシを作成させるだけで、任意のC#コードから任意のCOMインターフェイスを簡単に使用できます。COMと.NETを呼び出すときに常に発生するものを除いて、パフォーマンスのオーバーヘッドはありません。

逆に、C#アセンブリComVisibleAttributeをtrueに設定するだけで(VSではプロジェクトプロパティの単純なチェックボックスです)、コンパイラが自動的にCOMインターフェイスを作成します。繰り返しますが、追加のパフォーマンスペナルティはありません。

HTH!

于 2009-12-16T17:24:12.063 に答える