2

BSTR を in パラメーターとして受け取る ATL COM コンポーネント メソッドがあります。このメソッドへの各呼び出しを配列に追加する必要があります。SAFEARRAY は固定サイズであるため使用できないため、std::vector が最も簡単な選択になると考えていました。もちろん、ベクターに追加するたびに SysAllocString を呼び出す必要があります。これは、ベクトルが破棄される前に各エントリに対して SysFreeString を呼び出す必要があることを意味します。

私はより簡単でクリーンなソリューションを探していて、ベクターを vector<_bstr_t> として宣言することを考えていました。これには自動クリーンアップが含まれます。しかし、私の頭の片隅にあるのは、事実上スマート ポインターを標準のコンテナーに保持することに警鐘を鳴らしていることです。私の心配は正当化されますか、それとも安全にこれを行うことができますか? そうでない場合、他のより良い解決策はありますか?

4

4 に答える 4

4

[ についてvector< _bstr_t >] 私の心配は正当化されますか、それとも安全に行うことができますか?

はい。安全に使用できます_bstr_tが、それはスマート ポインターであるだけでなく、参照カウントスマート ポインターであることに注意してください。つまり追加費用。

そうでない場合、他のより良い解決策はありますか?

通常、 orのCComBSTR代わりにa を使用します。参照カウントが必要な場合は、に頼る必要があります。例: ATL も使用している場合は、おそらくs だけが必要になるでしょう。BSTR_bstr_t_bstr_tCComBSTR

CComBSTR クラスは、長さがプレフィックスされた文字列である BSTR のラッパーです。長さは、文字列内のデータの前のメモリ位置に整数として格納されます。

BSTR は、最後にカウントされた文字の後で null で終了しますが、文字列内に null 文字が埋め込まれている場合もあります。文字列の長さは、最初のヌル文字ではなく、文字数によって決まります。

したがって、選択を行う前に、次の点を考慮してください。

  1. _bstr_tは参照カウント スマート ポインター ラッパーですが、参照カウントBSTRは提供CComBSTR しません。
  2. _bstr_t address-of 演算子を再定義しないため、STL コンテナーに安全に格納できます。を使用CComBSTRする必要がありますCAdapt

CAdaptオブジェクトについて:

CAdapt は、アドレス取得演算子 (演算子 &) を再定義してオブジェクトのアドレス以外のものを返すクラスをラップするために使用される単純なテンプレートです。このようなクラスの例には、ATL の CComBSTR、CComPtr、CComQIPtr クラス、およびコンパイラ COM サポート クラス _com_ptr_t が含まれます。これらのクラスはすべて、データ メンバー (CComBSTR の場合は BSTR、他のクラスの場合はインターフェイス ポインター) のいずれかのアドレスを返すようにアドレス取得演算子を再定義します。

そして、次を使用できます。

typedef std::vector< CAdapt< CComBSTR > > MyString;
于 2012-06-19T15:08:07.917 に答える
1

_bstr_t は operator& をオーバーロードしないため、stl コンテナーで使用しても問題ありません。

于 2012-06-19T14:30:18.147 に答える
1

これなら安心してできると思います。禁止されていることの 1 つは、auto_ptr.

于 2012-06-19T13:53:06.360 に答える
0

BSTRあなたが呼び出す必要があるC構造体SysAllocStringですSysFreeString。 は、 and_bstr_tを呼び出す C++ 型であり、.では完全に 100% 安全です。オブジェクトを扱うときは、呼び出す必要はありませんし、呼び出すべきではありません。SysAllocStringSysFreeStringstd::vectorSysAllocStringSysFreeString_bstr_t

BSTR代わりに C 構造体オブジェクトを扱っている場合:
(1) スマート ポインターをコンテナーに安全に格納できますauto_ptr
(2) Avectorは を保存できますが、_bstr_t理解できない場合を除きSysFreeString、手動で呼び出す必要があります。はスマート ポインターではないdeleteため、生のポインターで行う必要があるのと同じように。 (3) aは、ベクトルへの完全に安全な格納を含め、オーバーヘッドなしで安全かつ魔法のようにすべてを行うスマート ポインターです。ただし、これは書き方が悪いため、ほとんどの人は次のように使用します。_bstr_t
std::unique_ptr<BSTR, HRESULT (*)(BSTR)>(mybstr, SysFreeAlloc)

template<class T, class F>
std::unique_ptr<T, F> make_unique(T t, F f)
{return std::unique_ptr<T,F>(std::move(t), std::move(f));}

typedef decltype(make_unique(declval<BSTR>(), SysFreeAlloc)) bstr_ptr;
std::vector<bstr_ptr> container;
container.push_back(make_unique(mybstr, SysFreeAlloc));
于 2012-06-19T14:46:09.750 に答える