Muss ich Strukturen löschen über Marshal.PtrToStructure in nicht verwalteten Code gemarshallt?

StackOverflow https://stackoverflow.com/questions/497133

  •  20-08-2019
  •  | 
  •  

Frage

Ich habe diesen C ++ Code:

extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo)
{
    *foo = new MY_DATA_STRUCTURE;

    //do stuff to foo
}

Dann in C # rufe ich die Funktion so:

[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;
}

Wo MyDataStructure ist eine Struktur (nicht-Klasse), die und die Mitglieder MY_DATA_STRUCTURE entspricht, werden entsprechend umgeleitet.

So Fragen: brauche ich pData zu speichern und ihn dann wieder los in nicht verwalteten Code, wenn MyDataStructure GC'd ist? MSDN sagt für Marshal.PtrToStructure (IntPtr, Type): „Marschälle Daten aus einem nicht verwalteten Speicherblock zu einem neu zugewiesenen verwalteten Objekt des angegebenen Typs.“ In diesem Satz bedeutet „Marshall“ bedeutet „Kopie“? In diesem Fall würde ich brauche (IntPtr pData) zu erhalten und dann gibt sie auf nicht verwalteten Code (in der MyDataStructure destructor), so kann ich ein C ++ tun „löschen“?

ich gesucht habe, aber ich kann eine ausreichend explizite Antwort auf diese nicht gefunden werden.

War es hilfreich?

Lösung

Wie Erik sagte, hat die Marschall Kopie bedeuten, aber ich glaube nicht, dass er den Hauptpunkt Ihrer Frage beantwortet.

Sie benötigen auf den pData nativen Zeiger zu halten, bis die MyDataStructure GCed ist? Nr.

Sobald gemarshallte, Ihre MyDataStructure Beispiel foo enthält eine Kopie der Struktur auf die pData zeigt. Sie müssen halten nicht auf pData mehr. Um einen Speicherverlust zu vermeiden, dass Sie pData in eine andere nicht verwaltete Funktion übergeben müssen, die es löschen, und das kann gleich nach dem Serialisieren getan werden, und zwar unabhängig davon, wie lange Sie halten an der MyDataStructure Instanz.

Andere Tipps

Ja, in diesem Fall bedeutet Marshall copy; So müssen Sie Ihr Gedächtnis in nicht verwalteten Code freizugeben. Alle Aufruf PtrToStructure liest eine Anzahl von Bytes, die von der Größe der Zielstruktur ‚MyDataStructure‘ aus der Speicherstelle angegeben, auf den pData.

Die Details hängen natürlich von genau das, was ‚MyDataStructure‘ sieht aus wie (verwenden Sie eine FieldOffset oder StructLayout in MyDataStructure Attribute.) - aber das Endergebnis ist, dass die Rückkehr von PtrToStructure ist eine Kopie der Daten

Wie GBegen weist darauf hin, in seine Antwort , habe ich nicht den Hauptpunkt Ihrer Frage beantworten. Ja, müssen Sie die nicht verwaltete Kopie Ihrer Struktur in nicht verwalteten Code löschen, aber nein, Sie müssen nicht auf pData halten -. Sie die nicht verwaltete Kopie löschen, sobald der Anruf an PtrToStructure abgeschlossen

PS:. Ich habe meinen Beitrag bearbeiten diese Informationen zu enthalten, um die Antworten zu einem Beitrag zu konsolidieren - wenn jemand diese Antwort upvotes, bitte GBegen Antwort als auch für seinen Beitrag upvote

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top