您的位置:首页 > 其它

平台调用P-INVOKE高级篇(一)--(封送含有二维数组的结构体)

2012-11-13 09:00 323 查看
对于结构体二维数组,看似简单,其实很复杂。很多人往往不知从何下手,在托管和非托管代码之间总是不能正确传递值。先用一个例子:
struct Lable1 {
BYTELabFilterChan0[4][256];
BYTELabFilterChan1[4][256];

}

这是曾经有人这样在C#进行定义的:
第一个:
[StructLayout(LayoutKind.Sequential)]
public class Label1 {
public byte[,]LabFilterChan0 = new byte[4, 256];
public byte[,]LabFilterChan1 = new byte[4, 256];
}

第二个:
public struct Label1{
byte[,]LabFilterChan0 = newbyte[4,256];
byte[,]LabFilterChan1 = new byte[4,256];
}

第三个:
public struct Label1{
byte[4,256]LabFilterChan0 ;
byte[4,256]LabFilterChan1 ;
}

咋一看,好像没什么问题!大家可以仔细看看,其实都有问题:
对于非托管和托管的结构体对应,关键就是两点:
1、两边的结构体大小要一致。
2、字节顺序要一致!
3、字符集。
其实第二点主要针对嵌套联合体来说的,没有嵌套联合体,一般按顺序字节方式即可:[StructLayout(LayoutKind.Sequential)]。对应嵌套联合体的结构体,将在下一篇进行讲解。 字符集比较好理解,就是Ansi和Unicode两种,即1个和2个字节。由于这个结构体没有包含字符串成员变量,所以,我们这里重点关注第一点!
对于简单类型的成员变量,如byte、short、int、float等,很容易跟C#的类型对应,MSDN专门有这个对应表,我这里不再重述。
回到这个例子,上面的三种转换错在哪里:
第一个:语法正确,内存空间8,而C++是1024!
第二个、第三个:C#语法就不允许,大家可以测试,看看报的什么语法错误,加深印象!
那么,正确做法是怎样呢?
第一种:拆分,也是最简单办法:
[StructLayout(LayoutKind.Sequential)]
public structByteStru {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[]a;
};

[StructLayout(LayoutKind.Sequential)]
public structLabel1 {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
publicByteStru[] LabFilterChan0 ;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ByteStru[] LabFilterChan1 ;
};

第二种:合并,这个比较复杂:
[StructLayout(LayoutKind.Sequential)]
public structLabel1 {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
publicbyte[] LabFilterChan0 ;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 1024)]
publicbyte[] LabFilterChan1 ;
};

这种办法,就把原来的二维数组,全部转为一个byte的一维数组,需要在使用做比较复杂处理:

public static byte[] MashalSimpleTwoArrayToBytes<T>(T[][] arr) {
introw = arr.GetLength(0);
intcol = arr.GetLength(1);
inttypeSize=Marshal.SizeOf(typeof(T));
inttotalLength=row*col*typeSize;
//开辟一个Byte 数组
byte[]allBuffuer = newbyte[totalLength];
intstartIndex = 0;
//然后依次把arr的数据拷贝到allBuffuer
for(int i = 0; i < row; i++)
{
arr[i].CopyTo(allBuffuer, startIndex);
startIndex+= typeSize * col;
}
returnallBuffuer;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: