2008-11-14 10 views

Odpowiedz

31

Najprostszym sposobem przekazania tablicy bajtów jest zadeklarowanie parametru w instrukcji importu jako tablicy bajtów.

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true] 
public extern static void Func(byte[]); 

byte[] ar = new byte[1000]; 
Func(ar); 

Powinieneś być również w stanie zadeklarować parametr jako IntPtr i Marszałek danych ręcznie.

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true] 
public extern static void Func(IntPtr p); 

byte[] ar = new byte[1000]; 
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(byte)) * ar.Length); 
Marshal.Copy(ar, 0, p, ar.Length); 
Func(p); 
Marshal.FreeHGlobal(p); 
+0

dlaczego pierwsze podejście zadziała, a drugie nie zadziała. Oto, co widzę w aplikacji na telefon z systemem Windows. – moubarak

+1

Wiem, że ten post jest trochę stary, ale 'Marshal.SizeOf (obiekt)' nie działa z tablicami. Jestem całkiem pewien, że dostaniesz wyjątek, jeśli przekażesz mu tablicę, ale nie mam teraz otwartego VS przede mną, aby spróbować. Aby poprawnie określić rozmiar tablicy, dla twojego przykładu kod miałby postać 'Marshal.SizeOf (typeof (byte)) * ar.Length'. – 9ee1

+0

Tak, masz rację 9ee1. Marshal.SizeOf może być użyty dla struktury, ale nie dla tablicy. Zaktualizowałem odpowiedni przykładowy kod. Dzięki. – asponge

6

Można użyć niebezpieczny kod:

unsafe 
{ 
    fixed(byte* pByte = byteArray) 
    IntPtr intPtr = new IntPtr((void *) pByte); 
    Func(intPtr); 
} 

Jeśli trzeba użyć bezpiecznego kodu, można użyć kilku sztuczek:

IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(byteArray)); 
Marshal.Copy(byteArray, 0, intPtr, Marshal.SizeOf(byteArray)); 

Func(intPtr); 

Marshal.FreeHGlobal(intPtr); 

Jednak bezpieczny kod będzie powolny IMHO .

3

Oto odpowiedni podpis dla natywnej funkcji.

[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")] 
public static extern void Func(System.IntPtr bytes) ; 
Powiązane problemy