2

gcroot<ManagedObject>.NET では、アンマネージ コードからのコールバックを提供するためにアンマネージ コードにマネージ オブジェクトを格納することに関して、比較的よく知られている問題があります。 「AppDomains 間で GCHandle を渡すことができません」というエラーが発生します。

この問題の標準的な修正方法は、デリゲートへの関数ポインターを使用することです。これは、デリゲートを使用して正しい AppDomain を「記憶」できるためです。http://lambert.geek.nz/2007/05/29/unmanaged-appdomainを参照-callback/で完全な説明が得られます。

ただし、このソリューションは少し複雑であり、デリゲートの有効期間を慎重に管理する必要があります。

管理対象オブジェクトに COM Callable Wrapper を使用しても同様に機能するようです: を格納する代わりにgcroot<ManagedObject>、ポインターをIUnknown *usingとして格納しGetIUnknownForObjectます。

m_value =
   static_cast<IUnknown*> (Marshal::GetIUnknownForObject(value).ToPointer());

GetObjectForIUnknown次に、コールバックを行う前に逆変換を行うことができます。IUnknown *欠点は、実際のオブジェクト型が失われ、後で次のようなものを使用してダウンキャストする必要があるため、型の安全性が少し失われることです。

IDisposable^ value =
      (IDisposable^) (Marshal::GetObjectForIUnknown(IntPtr(m_value)));

はどこにm_valueありIUnknown*ますか?

私はそれを試してみましたが、私のユースケースではうまくいくようですが、このアプローチをとることで問題はありますか? デリゲート ソリューションを使用する可能性のある場所ならどこでも適用できるように思われるので、それについて何かが欠けているのではないかと思います。

4

1 に答える 1

0

私は現在、このアプローチを本番環境で数か月間使用しており、問題は報告されていません。したがって、正確に決定的なものではありませんが、このアプローチは安全であると暫定的に結論付けます.

于 2013-09-25T13:47:51.027 に答える