我有一个托管对象,它需要传递给采用 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。显然我做错了什么 - 作为旁注,如何防止复杂对象上的“对象包含非原始或非 blittable 数据”错误?我必须编组每种类型吗?或者有没有更简单的方法来恢复对复杂托管对象的引用?
更新:
这是一个可能的修复吗?它似乎有效,但我不知道这种方法是否有任何问题。
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;
}