VB里面的结构体是一种WORD/DWORD对齐的结构体,这一点在编程中尤其要注意,如果是纯VB编程,则结构体的各个域如何排列可以基本不用关心,
而如果是调用API或者是调用其他的动态链接库,则很容易出问题,原因就在于:这些动态链接库是用C/C++写的,而大部分C/C++环境里的
结构体是非DWORD对齐的。这就导致调用动态链接库的时候,如果传一个结构体给一个动态链接库的接口函数,可能会导致不期望的结果;
经过实验,发现VB里面结构体的DWROD规则如下:
如果结构体里面类型最大的域的字节数大于等于4个字节:
1.结构体变量的起始地址必须是4的整数倍;
2.结构体的每个域的起始地址必须是4的整数倍;(如果需要,通过在前一个域的末尾补占位字节来达到该目的)
3.结构体的总的字节数必须是4的整数倍;(不够的话,在末尾补占位字节)
如果结构体里面类型最大的域的字节数等于2个字节(就是说最大的类型才是integer):
1.结构体变量的起始地址必须是2的整数倍;
2.结构体的每个域的起始地址必须是2的整数倍;(如果需要,通过在前一个域的末尾补占位字节来达到该目的)
3.结构体的总的字节数必须是2的整数倍;(不够的话,在末尾补占位字节)
如果结构体里面类型最大的域的字节数等于1个字节(就是说最大的类型才是Byte):
没有DWORD对齐规则,所有的域紧凑的排列,每个域紧密连在一起;也就是说:有几个域就有几个字节;
实验用代码如下,通过该代码可以清楚的窥探到VB结构体的存储规则:
-----------------------------------------------------
Option Explicit
Private Type aaa
f As Byte
g As Byte
x As Byte
y As Byte
z As Byte
a As Double
b As Integer
c As Byte
d As Byte
e As Byte
End Type
Private Type bbb
a As Byte
b As Integer
c As Byte
End Type
Private Type ccc
a As Byte
b As Double
End Type
Private Type ddd
a As Byte
b As Byte
e As Byte
f As Byte
g As Byte
End Type
Private Sub Command1_Click()
Dim s As aaa
MsgBox LenB(s)
MsgBox VarPtr(s) Mod 4
End Sub
Private Sub Command2_Click()
Dim x As bbb
MsgBox LenB(x)
MsgBox VarPtr(x) Mod 4
End Sub
Private Sub Command3_Click()
Dim x As ccc
MsgBox LenB(x)
End Sub
Private Sub Command4_Click()
Dim x As ddd
MsgBox LenB(x)
MsgBox VarPtr(x)
End Sub
-----------------------------------------------------
根据这个规则,会发现有时候声明同样的一个结构体,仅仅由于各个域的次序不同,就会导致结构体占用的空间大小不同的现象,
这也可用作一个程序优化技巧,减少程序的内存占用率;
例如:
Private Type bbb
a As Byte
b As Integer
c As Byte
End Type
Private Type bbb
a As Byte
c As Byte
b As Integer
End Type
两种声明方式完成的目的一样,但占用的内存空间是不一样的,显然后者会更节约内存;
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qiqi5521/archive/2006/06/23/826040.aspx