LPSAFEARRAY*outパラメータを介してSafeArrayを返すCOM関数があります。CComSafeArrayこの関数は、ATLのテンプレートクラスを使用してSafeArrayを作成します。私の素朴な実装はCComSafeArray<T>::Detach()、所有権をローカル変数から出力パラメーターに移動するために使用します。
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;
}
問題は、SafeArrayの新しい所有者(この場合はmain)が破棄されたときに、ロックがゼロではなく、SafeArrayのロック解除に失敗するように操作をCComSafeArray::Detach()実行することです(SafeArrayがないため、メモリリークが発生します)。割り当て解除)。UnlocksaDestroyE_UNEXPECTED
COMメソッドの境界を介してCComSafeArrays間で所有権を譲渡する正しい方法は何ですか?
編集:これまでの単一の回答から、エラーはmainサーバー側()ではなくクライアント側()にあるようですが、この些細なユースケース向けに設計されたものではないfooとは信じがたいです。 CComSafeArraySafeArrayをCOMメソッドからに取得するためのエレガントな方法になりますCComSafeArray。