2010-04-17 2 views
0

Par exemple. Je suivant la méthode de délégué que je veux utiliser en fonction de rappel avec le code non géré:Réception d'un objet dans une fonction de rappel non gérée

public delegate void Callback(IntPtr myObject); 

Callback callback; 

j'enregistrer de la manière suivante:

[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()); 

Maintenant, chaque fois que la fonction de rappel est appelée, elle aura un Pointeur/poignée d'un objet de la classe MyClass. Je pourrais utiliser Marshal.PtrToStructure pour convertir ceci en un objet de MyClass. Cependant, ce que je voudrais, c'est que la définition du délégué contienne déjà la classe MyClass. par exemple:

public delegate void Callback(MyClass myObject); 

J'ai essayé ceci, mais cela ne fonctionnera pas. J'ai essayé aussi ce qui suit, qui ne fonctionne pas:

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

Je suppose que je aurais besoin quelque chose comme « UnmarshalAs » à ce stade, mais malheureusement ce n'est pas disponible. Des suggestions comment je pourrais perdre de cette IntPtr dans ma fonction de rappel et obtenir un emballé comme un objet MyClass régulier et géré?

Répondre

2

GCHandle.FromIntPtr Method:

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

j'étais sur le point de revenir à dire que je trouve un moyen casting GCHandöe à un IntPtr et vice versa quand j'ai vu votre réponse à jour. Merci beaucoup l'homme :) –

Questions connexes