讨论VB中的结构体

讨论VB中的结构体[转载]
2009年10月20日 星期二 11:30


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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值