Получение объекта в неуправляемой функции обратного вызова - PullRequest
0 голосов
/ 17 апреля 2010

Например. У меня есть следующий метод делегата, который я хочу использовать в качестве функции обратного вызова с неуправляемым кодом:

public delegate void Callback(IntPtr myObject);

Callback callback;

Я регистрирую это следующим образом:

[DllImport("a.dll")]
public static void registerCallback(IntPtr callbackFunction, IntPtr anObject); 

// ...

this.myObject = new MyClass();
this.objectPin = GCHandle.Alloc(this.myObject, GCHandleType.Pinned);
registerCallback(Marshal.GetFunctionPointerForDelegate(callback), objectPin.AddrOfPinnedObject());

Теперь при вызове функции обратного вызова она будет иметь указатель / дескриптор объекта класса MyClass. Я мог бы использовать Marshal.PtrToStructure, чтобы преобразовать это в объект MyClass. Однако я хотел бы, чтобы определение делегата уже содержало класс MyClass. eg.:

public delegate void Callback(MyClass myObject);

Я пробовал это, но это не будет работать. Я также попробовал следующее, которое не сработало:

public delegate void Callback([MarshalAs(UnmanagedType.IUnknown)]MyClass myObject);

Полагаю, на данном этапе мне понадобится что-то вроде "UnmarshalAs", но, к сожалению, это недоступно. Любые предложения, как я могу потерять этот IntPtr в моей функции обратного вызова и получить его упакованным как обычный управляемый объект MyClass?

1 Ответ

2 голосов
/ 18 апреля 2010

Метод GCHandle.FromIntPtr :

void MyCallback(IntPtr anObject)
{
    GCHandle gch = GCHandle.FromIntPtr(anObject);
    MyClass myObject = (MyClass)gch.Target;
}
...