2010-03-26 12 views
11

Ich habe eine C-Funktion mit der folgenden Signatur:Wie marshaliere ich einen Zeiger auf ein Array von Zeigern auf Strukturen?

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

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

ich versuchte, die folgenden:

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

jedoch, dass Streckenposten, die Daten als ein Zeiger auf ein Feld von Strukturen, kein Zeiger auf ein Feld von Zeigern auf Strukturen.

Antwort

11

Ich glaube, Sie müssen einige der Marshalling manuell tun. Die Funktionsdeklaration sollte wie folgt aussehen:

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

Wir werden einige nativen Speicher zuweisen müssen und die Strukturen, um es Marschall, bevor es in 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 Mutter Funktion Ich werde diese Speicherplätze behalten und wiederverwenden, das wird nicht funktionieren. Wenn dies der Fall ist, halten Sie entweder den Speicher frei, bis Sie glauben, dass er nicht mehr verwendet wird, oder kopieren Sie die übergebenen Daten und lassen Sie die verwaltete Seite sofort nach dem Aufruf aufräumen.

Verwandte Themen