VB调用DLL(VC)使用结构体参数时的内存对齐及分配的问题.
结构内存对齐的相关说明:
第一:
首先要先计算结构中成员对齐:(VC编译器默认的一般是8字节对齐)用以来分配成员空间及偏移地址。结构体成员的对齐的取值来就是是用这个成员本身的大小和#pragma pack(push,n)中的n中较小的数对齐,例如如果成员大小为2,而你指定的对齐方式是4,则该成员按2对齐;注意是每个成员单独遵循自己的对齐原则.
分析方法:每个成员先取得自身的对齐值,然后看它前面已分配的空间是否是这个对齐值的倍数,如不是则将前面已分配的空间补齐成倍数,也就是用空字节了填充后,再从补好的位置开始分配自已所占的空间。
示例:如
struct Single_Command
{
int Command;
double beforehand;
};
内存中实际存储是这样的. XXXX****XXXXXXXX X代表1个字节, *代表一个空字节
第二:
最后要看整个结构对齐:对齐的原则结构本身的对齐是用结构中最大成员的大小和#pragma pack(push,n)中的n较小的数对齐,即最后的n的倍数.
分析方法:不是倍数时在结构的最后补空字节。
特殊情况:
1.包含指针类型的情况。只要记住指针本身所占的存储空间是4个字节就行了,而不必看它是指向什么类型的指针。
2.含有构造数据类型(数组、结构体和联合体)的情况。首先要明确的是计算存储空间时要把构造体看作一个整体来为其开辟存储空间;其次要明确的是在最后补齐时是按照所有元素中的基本数据类型元素的最长宽度来补齐的(包含成员对齐及结构对齐),也就是说虽然要把构造体看作整体,但在补齐的时候并不会按照所含结构体所占存储空间的长度来补齐的(即使它可能是最长的)。
注意事项;
VB默认的一般是4字节对齐
VC默认的一般是8字节对齐
问题示例:
VC中定义
struct Single_Command
{
int Command;
double beforehand;
};
VC内存中实际存储是这样的. XXXX****XXXXXXXX X代表1个字节, *代表一个空字节
VB中定义
Public Type Single_Command
Command As long
beforehand As double
End Type
VB内存中实际存储是这样的. XXXXXXXXXXXX X代表1个字节, *代表一个空字节
这时您就会发现当VB向VC传递结构数据时,VC是不能正错读取的.原因请根据前面的表述自行分析.
解决方法:
1.在VC使用#pragma pack(4)与#pragma pack()定义结构
2.在VB使用插入无用的空字节来补位。如:aaa As String * 4
更多分享请关注:软信网-编程-http://www.iis365.net.cn