dim a() as long
dim b() as byte
copymemory b(0),byval "1234",4
copymemory byval varptr(a(0)),1234,4
在 VB 中處於安全考慮,不能直接訪問內存,
但你可以使用 CopyMemory(RtlMoveMemory) 的 API 來復制指定區域的內存,
其具體聲明如下:
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
其中,
Destination 是指向復制目標的指針,可以直接指定為某個變量或是數組(如果是數組應使用 myArray(0) 或是 myArray(n) 來指定覆蓋的起點,不能直接使用 myArray),或是使用 ByVal 關鍵字加內存地址
Source 是復制源的指針,用法與上面一樣
Length 是復制的長度,以字節為單位。
VB 6 中沒有公開的三個函數:VarPtr,StrPtr,ObjPtr
它們分別返回變量、字符串、對象的指針(就是內存地址)
因此,在執行:
copymemory b(0),byval "1234",4
時,VB 會先在內存中划出一塊兒區域,
用於保存值為 "1234" 的字符串,
然后把這個字符串的指針傳給 CopyMemory,
CopyMemory 把內存中剛才保存字符串數據的地址處的數據復制到數組 b 中,
從 b(0) 開始覆蓋,覆蓋 4 個字節
VB 6 在調用 API 時,字符串一般是按值(ByVal)傳遞,
在傳遞時以 ANSI 編碼。
也就是說,上面那句代碼等價於(為了安全性,我個人推薦下面這種做法):
Erase b
b = StrConv("1234", vbFromUnicode)
而
copymemory byval varptr(a(0)),1234,4
其實就是
CopyMemory a(0),1234,4
在執行時,
VB 會先在內存中划出 2 個字節(1234 等價於 1234% 或是 CInt(1234))
用於保存值為 1234 的 Integer,
然后在執行 CopyMemory 時,
把內存中剛才保存有 1234 處的數據復制到數組 b 中,
從 a(0) 開始覆蓋,覆蓋 4 個字節。
問題是,
你把指針給人家時,只在對應的位置划了 2 個字節,
你卻要人家從你給的位置讀 4 個字節……
由於后兩個字節沒有被分配,
因此可能會返回一個任意值,
不排除崩潰的可能,
而且還是你的程序帶着開發環境 IDE 一塊兒崩潰。
估計你本來應該這么寫(我覺得 byval varptr(...) 累贅了):
CopyMemory a(0),1234&,4
這樣,划出來的就是 4 個字節(Long)了。
可是,如果是這樣,那你還不如用:
a(0) = 1234
又方便,又安全……
還有,
CopyMemory 只負責復制,不負責分配內存。
因此你在把 a、b 數組當成復制覆蓋的目標之前,
至少需要分配一下內存吧(若你是在問題中省略了就算了……)
例如:
ReDim a(0) '4 x 1 = 4 字節
ReDim b(3) '1 x 4 = 4 字節
但如果你准備使用
b = StrConv("1234", vbFromUnicode)
這樣的代碼,
則 b 一定要是空的,如果不是,則需要使用 Erase 清空