2010-03-26 31 views
11

Aşağıdaki imza ile C işlevi vardır:İşaretçiyi yapılara gösteren bir diziye nasıl işaretlerim?

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

playersstruct player nesnelere işaretçiler bir dizi için bir işaretçidir. n dizideki işaretçi sayısıdır. İşlev diziyi veya yapıların içeriğini değiştirmez ve geri döndükten sonra herhangi bir gösterici tutmaz. ,

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

Ancak bu yapılar dizisine değil, yapılarına işaretçiler bir dizi için bir işaretçi için mareşalinden bir işaretçi olarak veri:

Aşağıdaki çalıştı.

cevap

11

Marşlama işleminin bazılarını el ile yapmanız gerekeceğini düşünüyorum. fonksiyon bildirimi aşağıdaki gibi görünmelidir:

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

Bazı yerli bellek ve yerli işlevine bunu geçirmeden önce kendisine yapıları sıralamakta gerekir: Kendi ana fonksiyonu ise

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

Bu bellek konumlarını beklemeye ve yeniden kullanacak, bu işe yaramaz. Böyle bir durumda, artık kullanılmadığını düşündükçe veya yerel yöntemde aktarılan verileri kopyalayana kadar hafızayı boşaltmaya devam edin ve yönetilen taraf çağrıdan hemen sonra hafızasını temizlemesine izin verin.

İlgili konular