6

wchar__t オブジェクトにコピーするために変換したい BSTR オブジェクトがあります。注意が必要なのは、BSTR オブジェクトの長さが数キロバイトから数百キロバイトになる可能性があることです。データをコピーする効率的な方法はありますか? wchar_t 配列を宣言するだけで、保持する必要がある可能性のある最大のデータを常に割り当てることができることはわかっています。ただし、これは、数キロバイトしか必要としない可能性があるものに数百キロバイトのデータを割り当てることを意味します。助言がありますか?

4

5 に答える 5

10

まず、コンテンツを読むだけであれば、実際には何もする必要がないかもしれません。BSTR 型は、既に null で終わる wchar_t 配列へのポインターです。実際、ヘッダーを確認すると、BSTR は基本的に次のように定義されていることがわかります。

typedef BSTR wchar_t*;

そのため、セマンティクスが異なっていても、コンパイラはそれらを区別できません。

重要な注意点が 2 つあります。

  1. BSTR は不変であると想定されています。BSTR を初期化した後は、その内容を決して変更しないでください。「変更」する場合は、新しいポインターを作成して新しいポインターを割り当て、古いポインターを解放する必要があります (所有している場合)。
    [更新:これは真実ではありません。ごめん!BSTR はその場で変更できます。私はめったにその必要がありませんでした。]

  2. BSTR には埋め込みの null 文字を含めることができますが、従来の C/C++ 文字列には含めることができません。

BSTR のソースをかなり制御でき、BSTR に NULL が埋め込まれていないことを保証できる場合は、BSTR を wchar_t であるかのように読み取り、従来の文字列メソッド (wcscpy など) を使用して、アクセスします。そうでなければ、あなたの人生はより困難になります。より多くの BSTR として、または動的に割り当てられた wchar_t の配列として、常にデータを操作する必要があります。ほとんどの文字列関連の関数は正しく動作しません。

自分のデータを管理していると仮定しましょう。NULL について心配する必要はありません。また、実際にコピーを作成する必要があり、既存の BSTR を直接読み取ることができないと仮定しましょう。その場合、次のようなことができます。

UINT length = SysStringLen(myBstr);        // Ask COM for the size of the BSTR
wchar_t *myString = new wchar_t[lenght+1]; // Note: SysStringLen doesn't 
                                           // include the space needed for the NULL

wcscpy(myString, myBstr);                  // Or your favorite safer string function

// ...

delete myString; // Done

BSTR にクラス ラッパーを使用している場合、ラッパーには SysStringLen() を呼び出す方法が必要です。例えば:

CComBString    use .Length();
_bstr_t        use .length();

更新:これは、私よりもはるかに知識のある人によるこの主題に関する優れた記事です:
「Eric [Lippert]のBSTRセマンティクスの完全ガイド」

更新: 例で strcpy() を wcscpy() に置き換えました

于 2008-09-16T15:59:55.610 に答える
5

BSTR オブジェクトには長さのプレフィックスが含まれているため、長さを調べるのは簡単です。長さを調べ、結果を保持するのに十分な大きさの新しい配列を割り当て、それに処理し、完了したら解放することを忘れないでください。

于 2008-09-16T13:10:07.407 に答える
4

変換の必要はありません。ポインターは文字列のBSTR最初の文字を指し、ヌルで終了します。長さは、メモリ内の最初の文字の前に格納されます。BSTRs は常に Unicode (UTF-16/UCS-2) です。ある段階では「ANSI BSTR」と呼ばれるものがありました。レガシー API にはいくつかの参照がありますが、現在の開発ではこれらを無視できます。

BSTRこれは、を期待する任意の関数に安全に を渡すことができることを意味しますwchar_t

Visual Studio 2008 では、はネイティブ型であるのに対し、はBSTRへのポインターとして定義されているため、コンパイラ エラーが発生する場合があります。キャストするか、コンプライアンスをオフにすることができます。unsigned shortwchar_twchar_t/Zc:wchar_t

于 2008-09-16T14:16:21.490 に答える
3

覚えておくべきことの1つは、BSTR文字列にはnullが埋め込まれている可能性があり、多くの場合、含まれているということです。nullは、文字列の終わりを意味するものではありません。

于 2008-09-16T14:25:07.150 に答える
0

ATL と CStringT を使用すると、代入演算子を使用できます。または、USES_CONVERSION マクロを使用することもできます。これらはヒープ割り当てを使用するため、メモリ リークを防ぐことができます。

于 2008-09-16T13:12:59.273 に答える