私は、wchar__tオブジェクトにコピーするために変換したいBSTRオブジェクトを持っています。トリッキーなことは、BSTRオブジェクトの長さが数キロバイトから数百キロバイトになることです。データを効率的にコピーする方法はありますか?私はwchar_t配列を宣言するだけで、常に保持する必要のある最大限のデータを割り当てることができます。しかし、これは、何キロバイトしか必要としない何百万キロバイトのデータを割り当てることを意味する。助言がありますか?BSTRを効率的にwchar_t []にコピーしますか?
答えて
BSTRオブジェクトには長さ接頭辞が含まれているため、長さを見つけるのが安いです。長さを調べ、結果を保持するのに十分な大きさの新しい配列を割り当て、その中で処理し、完了したら解放することを忘れないでください。
ATLとCStringTを使用すると、代入演算子を使用できます。あるいは、USES_CONVERSIONマクロを使うことができます。これらはheap allocを使用しているため、メモリがリークしないことを保証します。
変換の必要はありません。 A BSTR
ポインタは文字列の最初の文字を指しており、NULLで終了します。長さはメモリの最初の文字の前に格納されます。 BSTR
は常にUnicode(UTF-16/UCS-2)です。 ANSI BSTRと呼ばれるものがありました。これまでのAPIにはいくつかの参考文献がありますが、現在の開発ではこれらを無視することができます。
これは、wchar_t
を期待する機能に安全にBSTR
を渡すことができることを意味します。
BSTR
はunsigned short
へのポインタとして定義されているため、Visual Studio 2008ではコンパイラエラーが発生することがあります。wchar_t
はネイティブタイプです。 wchar_t
をキャストするかオフにするかは、/Zc:wchar_t
にすることができます。
文字列BSTR
には、埋め込まれたNULLが含まれていることが多く、よくあることです。 nullは文字列の末尾を意味するものではありません。
まず、実際には何もする必要はありません。必要なのは内容を読むだけなのです。 BSTR型はすでにnullで終了するwchar_t配列へのポインタです。
typedef BSTR wchar_t*;
ので、コンパイラはそれらが異なる意味を持っているにもかかわらず、それらを区別することはできません:あなたは、ヘッダーをチェックすると、実際には、あなたはBSTRは、基本的にのように定義されていることがわかります。
重要な注意点が2つあります。
BSTRは不変であるはずです。 BSTRが初期化された後は、BSTRの内容を決して変更しないでください。あなたが「変更する」場合は、新しいポインタを割り当てて新しいポインタを割り当て、古いポインタを解放する必要があります(所有している場合)。
[UPDATE:これは正しくありません。ごめんなさい!その場でBSTRを変更することができます。私は非常に必要性はほとんどありません。]従来のC/C++文字列は埋め込まれていないヌル文字を含むことができます。
あなたがBSTRのソースの制御のかなりの量を持っている、とBSTRは埋め込まれたヌルを持っていないことを保証することができる場合、あなたはそれがwchar_t型であるかのようにBSTRから読み取られ、従来の文字列を使用することができますそれにアクセスするためのメソッド(wcscpyなど)そうでなければ、あなたの人生はますます難しくなります。より多くのBSTRとして、または動的に割り当てられたwchar_tの配列として、常にデータを操作する必要があります。ほとんどの文字列関連関数は正しく動作しません。
データを制御したり、NULLを心配したりしないとしましょう。コピーを作成する必要があり、既存のBSTRを直接読み取ることはできないと仮定しましょう。その場合、あなたはこのような何か行うことができます:あなたは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
を、ラッパーはあなたのためのSysStringLen()を呼び出す方法を持っている必要があります。たとえば、次のように
CComBString use .Length();
_bstr_t use .length();
UPDATE:これは、はるかに精通し私よりも誰かによって被験者に良い記事です:
"Eric [Lippert]'s Complete Guide To BSTR Semantics"
UPDATE:wcscpyに置き換えのstrcpy()()内例
AFAIK、BSTRは*不変*ではないと思われます。だから彼らはconst *と宣言されていないのです。 – Constantin
Hmmm ...私の立場を支持する参考文献は見つかりません。私が考えていたことは何でしょう?私はそれを訂正します。 –
strcpyの代わりにwcscpyを使用してはいけませんか? – arolson101
- 1. ノードコレクションを効率的にコピーして扱い、シリアル化しますか?
- 2. 行列を効率的に新しい行列にコピー
- 3. ExcelからWord配列(VBA)に効率的に範囲をコピー
- 4. 配列やarraylistsを効率的にコピーするには?
- 5. 大きな表を別の表に効率的にコピーする
- 6. OpenGL ES 2.0 - テクスチャをフレームバッファに効率的にコピーする方法
- 7. 同じFileSystem内のファイルを効率的にコピーする方法
- 8. が効率的に
- 9. ネットワークを介してファイルを効率的にコピーするためのアルゴリズム
- 10. ボクセル内の球面を効率的に描画しますか?
- 11. Android:効率的にキャンバスの内容をスクロールしますか?
- 12. テキストからWikiDataエンティティを効率的に抽出します。
- 13. ノードを効率的にグループ化しますか?
- 14. Java:効率的にboolean [32]を格納しますか?
- 15. Linuxファイルシステムは効率的にファイルをキャッシュしますか?
- 16. を効率的
- 17. を効率的
- 18. あるファイルから別のファイルへの効率的なコピー
- 19. GCDでファイルをコピーする最も効率的な方法は?
- 20. 効率的に画像
- 21. が効率的にsitutation
- 22. は、効率的にハイパーリンク
- 23. ScalaはSparkで非効率的に収集しますか?
- 24. S3フォルダを新しい名前に効率的にコピーすることは可能ですか
- 25. Redisデータベースに効率的にアクセスする
- 26. c#SqlDataReaderからXElementへ効率的に
- 27. 効率的
- 28. ImmutableMapを効率的に「変更する」
- 29. Windowsイベントログを効率的にクエリする
- 30. テーブルを効率的に比較する
wchar_tは正確にshortのサイズであることは保証されていません。 – ben
私はこの操作は常に安全だと思っていますが、期待される結果が得られるとは限りません。 BSTRはその本体にヌル文字(したがって長さ接頭辞)を含むことができますが、wchar_t *を期待する関数は最初のヌル文字を文字列の最後と解釈します。 – Martin
"あなたはwchar_t *を期待している関数にBSTRを安全に渡すことはできません"。 SysStringLen(NULL)とwcslen(NULL)を比較してください。 – Constantin