私は、LPSAFEARRAY*
outパラメータを介してSafeArrayを返すCOM関数を持っています。 この関数は、ATLのCComSafeArray
テンプレートクラスを使用してSafeArrayを作成します。 私の単純な実装は、出力パラメータにローカル変数の所有権を移動するためにCComSafeArray<T>::Detach()
を使用する:ローカルCComSafeArrayをLPSAFEARRAY出力パラメータに戻すにはどうすればよいですか?
void foo(LPSAFEARRAY* psa)
{
CComSafeArray<VARIANT> ret;
ret.Add(CComVariant(42));
*psa = ret.Detach();
}
int main()
{
CComSafeArray<VARIANT> sa;
foo(sa.GetSafeArrayPtr());
std::cout << sa[0].lVal << std::endl;
}
問題はCComSafeArray::Detach()
がUnlock
動作を行うことになるようにするときのSafeArray(メインのsa
この中の新しい所有者case)が破損した場合、ロックはゼロではなく、Destroy
はE_UNEXPECTED
でSafeArrayのロックを解除できません(SafeArrayが割り当て解除されていないため、メモリリークが発生します)。
COMメソッド境界を通じてCComSafeArrayに所有権を転送する正しい方法は何ですか?
編集:単一の回答からは、これまでのところ、エラーがサーバ側(foo
)からクライアント側(main
)とではない上にあるようですが、私はそれは難しいことCComSafeArray
wasn信じることを見つけますこの単純なユースケースのために設計されたものでは、SafeメソッドをCOMメソッドから取り出してCComSafeArray
にするエレガントな方法が必要です。
使用しているVisual Studioのバージョンはどれですか? –
これはVS8(2005)とVS9(2008)の両方で発生します – Motti
私の経験に基づいて、CComSafeArrayを設計した人は決してそれを実際に使用したことはありません。必要に応じて独自のラッパークラスを使用できます。 – Amnon