dim a() as longdim 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 清空
VB中ByVal與ByRef有什麼區別
byval是值傳遞 byref是位址傳遞。在交換函式裡單純交換值時沒有效果的,需要交換對應的位址。主要區別 1 引用引數 ref 在可以作為引用引數在函式成員呼叫中傳遞之前,必須已明確賦值,而輸出引數 out 在可以作為輸出引數在函式成員呼叫中傳遞之前不一定要明確賦值,在該函式成員正常返回前都必須已...
中引用vb編寫的
private declare sub make lib makebar.dll ucdata as byte,byval nlen as long,byval szfilename as string,byval nclumn as long,byval nerr as long,byval nh...
VB中listview 的FindItem用法
finditem 方法 listview 控制項 查詢並返回 listview 控制項中 listitem 物件的引用。語法object.finditem string,value,index,match finditem 方法的語法包含下面部分 部分 描述 object 必需的。物件表示式,其值是...