2

IntPtr を受け取るアンマネージ コードのイベント ハンドラーに渡す必要があるマネージ オブジェクトがあります。何が間違っているのか、または私のアプローチが正しいのかどうかはよくわかりません。私が理解しているように、GCがオブジェクトを収集しないようにするには、次のようにオブジェクトを固定する必要があります。

MyCustomObject managedObject = new MyCustomObject();
GCHandle handle = GCHandle.Alloc(managedObject, GCHandleType.Pinned);
CustomEventHandler eventDelegate = new CustomEventHandler(PropertyEvent);
UnmanagedEventHandler(eventDelegate, handle.AddrOfPinnedObject());

private uint PropertyEvent(IntPtr inContext)
{
    GCHandle handle = GCHandle.FromIntPtr(inContext); // throws exception
    MyCustomObject managedObject = (MyCustomObject)handle.Target;
}

イベント内のオブジェクトへの参照を取得しようとすると、FatalExecutionEngineError が発生します。明らかに私は何か間違ったことをしています - そして補足として、複雑なオブジェクトで「オブジェクトに非プリミティブまたは非ブリット可能データが含まれています」というエラーをどのように防ぐのですか? すべてのタイプをマーシャリングする必要がありますか? または、複雑な管理対象オブジェクトへの参照を回復する簡単な方法はありますか?

更新

これは可能な修正ですか?うまくいくようですが、このアプローチに何か問題があるかどうかはわかりません。

MyCustomObject managedObject = new MyCustomObject();
GCHandle handle = GCHandle.Alloc(managedObject, GCHandleType.Normal);
IntPtr ptr = GCHandle.ToIntPtr(handle);
CustomEventHandler eventDelegate = new CustomEventHandler(PropertyEvent);
UnmanagedEventHandler(eventDelegate, ptr);

private uint PropertyEvent(IntPtr inContext)
{
    GCHandle handle = GCHandle.FromIntPtr(inContext); // throws exception
    MyCustomObject managedObject = (MyCustomObject)handle.Target;
}
4

1 に答える 1