我有一个“C”结构,定义为:
typedef unsigned char tUI8;
typedef struct
{
tUI8 Mode;
tUI8 Data[16];
} TestStruct;
一个函数,它接受一个指向这个结构的指针并填充数据:
void FillTest(tUI8 Mode, TestStruct *s);
为了PInvoke这个函数,我把C#代码编写为:
[StructLayout(LayoutKind.Sequential)]
struct TestStruct
{
public byte Mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Data;
}
static class NativeTest
{
[DllImport("Native.dll")]
public static extern void FillTest(byte mode, ref TestStruct s);
}
这有效但我怀疑在PInvoke marshaller期间在调用期间复制结构并返回而不是固定它。我可以这么说,因为即使我没有初始化结构,它也能正常工作。
TestStruct s;
//here s.Data == null!
NativeTest.FillTest(10, ref s); //<<< I expected an error here
//here s.Data points to a valid byte[] of length 16
Console.WriteLine(BitConverter.ToString(s.Data));
我的问题是如何使用struct或class定义PInvoke签名,以避免在编组期间复制数据?
答案 0 :(得分:2)
我怀疑你想要一个fixed size buffer,它将内联你的结构中的数据:
[StructLayout(LayoutKind.Sequential)]
unsafe struct TestStruct
{
public byte Mode;
public fixed byte Data[16];
}
您现在应该可以通过引用将其直接传递给您的非托管代码。 (您还需要明确允许不安全的代码。)
我不知道你需要使用什么属性进行编组,如果有的话,但值得一试......
答案 1 :(得分:0)
这可以在不使用不安全代码的情况下完成。
通过编组作为ByValArray
[StructLayout(LayoutKind.Sequential)]
struct TestStruct
{
public byte Mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Data;
}