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