我愛北京天安門
天安門上太陽升
偉大領袖毛主席
指引我們向前進
<p>VB裡面的結構體是一種WORD/DWORD對齊的結構體,這一點在編程中尤其要注意,如果是純VB編程,則結構體的各個域如何排列可以基本不用關心,<br />而如果是調用API或者是調用其他的動態連結程式庫,則很容易出問題,原因就在於:這些動態連結程式庫是用C/C++寫的,而大部分C/C++環境裡的<br />結構體是非DWORD對齊的。這就導致調用動態連結程式庫的時候,如果傳一個結構體給一個動態連結程式庫的介面函數,可能會導致不期望的結果;</p><p>經過實驗,發現VB裡面結構體的DWROD規則如下:</p><p>如果結構體裡面類型最大的域的位元組數大於等於4個位元組:<br
/>1.結構體變數的起始地址必須是4的整數倍;<br />2.結構體的每個域的起始地址必須是4的整數倍;(如果需要,通過在前一個域的末尾補佔位位元組來達到該目的)<br />3.結構體的總的位元組數必須是4的整數倍;(不夠的話,在末尾補佔位位元組)</p><p>如果結構體裡面類型最大的域的位元組數等於2個位元組(就是說最大的類型才是integer):<br />1.結構體變數的起始地址必須是2的整數倍;<br />2.結構體的每個域的起始地址必須是2的整數倍;(如果需要,通過在前一個域的末尾補佔位位元組來達到該目的)<br
/>3.結構體的總的位元組數必須是2的整數倍;(不夠的話,在末尾補佔位位元組)</p><p>如果結構體裡面類型最大的域的位元組數等於1個位元組(就是說最大的類型才是Byte):<br />沒有DWORD對齊規則,所有的域緊湊的排列,每個域緊密連在一起;也就是說:有幾個域就有幾個位元組;</p><p><br />實驗用代碼如下,通過該代碼可以清楚的窺探到VB結構體的儲存規則:<br />-----------------------------------------------------<br />Option Explicit</p><p>Private
Type aaa<br /> f As Byte<br /> g As Byte<br /> x As Byte<br /> y As Byte<br /> z As Byte<br /> a As Double<br /> b As Integer<br /> c As Byte<br /> d As Byte<br /> e As Byte<br />End Type</p><p><br />Private
Type bbb<br /> a As Byte<br /> b As Integer<br /> c As Byte<br />End Type</p><p>Private Type ccc<br /> a As Byte<br /> b As Double<br />End Type</p><p>Private Type ddd<br
/> a As Byte<br /> b As Byte<br /> e As Byte<br /> f As Byte<br /> g As Byte<br />End Type</p><p><br />Private Sub Command1_Click()<br />Dim s As aaa<br />MsgBox LenB(s)<br
/>MsgBox VarPtr(s) Mod 4<br />End Sub</p><p>Private Sub Command2_Click()<br />Dim x As bbb</p><p>MsgBox LenB(x)<br />MsgBox VarPtr(x) Mod 4</p><p>End Sub</p><p>Private Sub Command3_Click()<br />Dim x As ccc<br />MsgBox LenB(x)<br />End Sub</p><p>Private Sub
Command4_Click()<br />Dim x As ddd<br />MsgBox LenB(x)<br />MsgBox VarPtr(x)<br />End Sub<br />-----------------------------------------------------</p><p>根據這個規則,會發現有時候聲明同樣的一個結構體,僅僅由於各個域的次序不同,就會導致結構體佔用的空間大小不同的現象,<br />這也可用作一個程式最佳化技巧,減少程式的記憶體佔用率;</p><p>例如:<br
/>Private Type bbb<br /> a As Byte<br /> b As Integer<br /> c As Byte<br />End Type</p><p>Private Type bbb<br /> a As Byte<br /> c As Byte<br /> b As
Integer<br />End Type</p><p>兩種聲明方式完成的目的一樣,但佔用的記憶體空間是不一樣的,顯然後者會更節約記憶體;</p>