C API署名の例:
void Func(unsigned char* bytes);
Cでは、配列へのポインターを渡したい場合、次のことができます。
unsigned char* bytes = new unsigned char[1000];
Func(bytes); // call
上記のAPIをP/Invokeに変換して、C#バイト配列へのポインターを渡すにはどうすればよいですか?
バイトの配列を渡す最も簡単な方法は、インポートステートメントでパラメータをバイト配列として宣言することです。
[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true]
public extern static void Func(byte[]);
byte[] ar = new byte[1000];
Func(ar);
また、パラメーターをIntPtrとして宣言し、データを手動でマーシャリングできる必要があります。
[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);
安全でないコードを使用できます:
unsafe
{
fixed(byte* pByte = byteArray)
IntPtr intPtr = new IntPtr((void *) pByte);
Func(intPtr);
}
安全なコードを使用する必要がある場合は、いくつかのトリックを使用できます。
IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(byteArray));
Marshal.Copy(byteArray, 0, intPtr, Marshal.SizeOf(byteArray));
Func(intPtr);
Marshal.FreeHGlobal(intPtr);
ただし、安全なコードは私見では遅くなります。
ネイティブ関数の適切なシグネチャは次のとおりです。
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")]
public static extern void Func(System.IntPtr bytes) ;