12 Stimmen

Wie marshal ich einen Zeiger auf ein Array von Zeigern auf Strukturen?

Ich habe eine C-Funktion mit der folgenden Signatur:

int my_function(int n, struct player **players)

players ist ein Zeiger auf ein Array von Zeigern auf struct player Objekte. n ist die Anzahl der Zeiger im Array. Die Funktion verändert weder das Array noch den Inhalt der Strukturen und behält nach der Rückkehr keine Zeiger zurück.

Ich habe Folgendes versucht:

[DllImport("mylibary.dll")]
static extern int my_function(int n, 
    [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] 
     player_in []players);

Allerdings, dass die Daten als ein Zeiger auf ein Array von Strukturen, nicht ein Zeiger auf ein Array von Zeigern auf Strukturen marshalen.

11voto

RandomEngy Punkte 14379

Ich glaube, Sie müssen einen Teil der Rangierarbeiten manuell durchführen. Die Funktionsdeklaration sollte wie folgt aussehen:

[DllImport("mylibary.dll")]
private static extern int my_function(int n, IntPtr players);

Wir müssen nativen Speicher zuweisen und die Strukturen in diesen Speicher einordnen, bevor wir ihn an die native Funktion übergeben:

private static void CallFunction(Player[] players)
{
    var allocatedMemory = new List<IntPtr>();

    int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
    IntPtr nativeArray = Marshal.AllocHGlobal(intPtrSize * players.Length);
    for (int i = 0; i < players.Length; i++)
    {
        IntPtr nativePlayer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Player)));
        allocatedMemory.Add(nativePlayer);
        Marshal.StructureToPtr(players[i], nativePlayer, false);

        Marshal.WriteIntPtr(nativeArray, i * intPtrSize, nativePlayer);
    }

    my_function(players.Length, nativeArray);

    Marshal.FreeHGlobal(nativeArray);

    foreach (IntPtr ptr in allocatedMemory)
    {
        Marshal.FreeHGlobal(ptr);
    }
}

Wenn Ihre systemeigene Funktion diese Speicherplätze beibehält und wiederverwendet, wird dies nicht funktionieren. Wenn dies der Fall ist, warten Sie entweder mit dem Freigeben des Speichers, bis Sie denken, dass er nicht mehr verwendet wird, oder kopieren Sie in der nativen Methode die übergebenen Daten und lassen Sie die verwaltete Seite ihren Speicher unmittelbar nach dem Aufruf aufräumen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X