0

非常に長い文字列を持つ「const char* str」があります。cpp クライアントから、BSTR タイプを想定する .Net COM メソッドに渡す必要があります。現在私は使用しています:

CComBSTR bstr = str;

これには次の問題があります。

  • この行がメモリ不足のメッセージで失敗することがあります
  • bstr を COM クラスに渡すと、大量のメモリ (文字列サイズよりもはるかに多く) が必要になるため、メモリ不足で失敗する可能性があります。

質問:

  • 賢明に CComBSTR に変換していますか? たとえば、ヒープなどを使用する方法はありますか
  • 代わりに BSTR を使用する方が良いですか?

その他のご提案も大歓迎です...

4

3 に答える 3

3

BSTRメソッドがパスを期待している場合、 aBSTRが唯一の正しい方法です。

に変換するchar*には、変換とメモリ割り当てに Win32 API 関数をBSTR使用します。それを回避することはできません。メモリの割り当てが必要です。そうしないと、COM サーバーが を呼び出すと失敗します。MultiByteToWideChar()SysAllocStringLen()SysAllocStringLen()SysStringLen()

を使用してそれCComBSTRに割り当てるchar*と、同じシーケンスが実行されます - ATL はヘッダーとして利用可能であり、それを読んでそれがどのように機能するかを楽しむことができます。したがって、実際CComBSTRには、必要なアクションの最小限のセットを正確に実行します。

BSTRCOM サーバーに渡すと、ラップされたCComBSTR::operator BSTR() constオブジェクトへのポインターを返すだけの呼び出しが呼び出されます。本体はコピーされません。次に何が起こるかは、使用されている COM サーバーまたは相互運用機能次第です。ボディをコピーするか、単に直接読み取るかは、自分で決定します。BSTRBSTRBSTR

メモリ不足を解決するための唯一の方法は、COM インターフェイスを変更して、一部のリーダーを受け入れ、そのリーダーを介してチャンクでデータを要求することです。

于 2009-10-20T05:17:14.920 に答える
1

それはインプロセス COM サーバーですか、そのコードはありますか、それともサード パーティですか? これは、実際の char* ポインターを COM サーバーに渡すことができ、allocate+copy+free の代償を支払う必要がないためです。C++ クライアントのみが使用できる新しいメソッド/プロパティを追加する必要があります。


BSTR を渡す代わりに、char* をStreamインターフェイスでラップできます。.NET サーバーはStream、文字列ではなく a を取得する必要があります。

C++ 側では、COM インターフェイスをサポートする COM クラスを実装しIStreamます。このクラスは、char* をラップする読み取り専用ストリームです。このクラスをUCOMIStreamインターフェイスとして .NET サーバーに渡すことができます。
.NET 側では、UCOMIStreamメソッドを使用して文字列を読み取ります。1 回のパスでストリーム全体を読み取らないように注意してください。

于 2009-10-19T15:37:07.447 に答える
0

CComBSTRは、BSTRのラッパーであり、BSTRは、特別な終了を伴うUnicode文字列としてカウントされます。

したがって、対応するchar *形式の約2倍のサイズになると予想されます(主に1バイト文字を使用する文字セットの場合)。

デストラクタはBSTRに関連付けられたメモリを解放するため、CComBSTRを使用することをお勧めします。

于 2009-10-19T15:35:41.757 に答える