| 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 |