Ho questo codice C++:Devo eliminare le strutture sottoposte a marshalling tramite Marshal.PtrToStructure nel codice non gestito?
extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo)
{
*foo = new MY_DATA_STRUCTURE;
//do stuff to foo
}
Poi in C# chiamo la funzione così:
[DllImport("MyDll.dll")]
static extern void AllocateFoo(out IntPtr pMyDataStruct);
...
MyDataStructure GetMyDataStructure()
{
IntPtr pData;
ManagedAllocateFooDelegate(out pData);
MyDataStructure foo = (MyDataStructure)Marshal.PtrToStructure(pData, typeof(MyDataStructure));
return foo;
}
Dove MyDataStructure è una struttura (non classe) che corrisponde alla MY_DATA_STRUCTURE e membri sono marshalling appropriato.
Quindi domande: devo memorizzare pData e poi rilasciarlo di nuovo nel codice non gestito quando MyDataStructure è GC'd? MSDN dice per Marshal.PtrToStructure (IntPtr, Type): "Esegue il marshaling dei dati da un blocco di memoria non gestito a un oggetto gestito appena assegnato del tipo specificato." In questa frase "Marshall" significa "copia"? In tal caso, dovrei conservare (IntPtr pData) e poi passarlo a codice non gestito (nel distruttore MyDataStructure) in modo da poter eseguire un "delete" C++?
Ho cercato ma non riesco a trovare una risposta sufficientemente esplicita per questo.
La tua funzione non gestita, AllocateFoo, non funziona come scritto. È necessario un livello aggiuntivo di riferimento indiretto per riportare il puntatore al chiamante. e, AllocateFoo (MY_DATA_STRUCTURE * * foo) { * foo = new MY_DATA_STRUCTURE; } – GBegen
Sì hai ragione! Il mio codice attuale utilizza PMY_DATA_STRUCTURE *, modifico il post. – Serguei