全面攻略VB.NET指針應(yīng)用
經(jīng)過長時間學(xué)習(xí)VB.NET,于是和大家分享一下VB.NET指針應(yīng)用,看完本文你肯定有不少收獲,希望本文能教會你更多東西。VB里使用指針不象C里那樣靈活,用指針處理數(shù)據(jù)時都需要用CopyMemory將數(shù)據(jù)在指針和VB能夠處理的變量之間來回拷貝,這需要很大的額外開銷。因此不是所有C里的指針操作都可以移值到VB里來,我們只應(yīng)在需要的時候才在VB里使用指針。
1、VB.NET指針應(yīng)用動態(tài)內(nèi)存分配:完全不可能、可能但不可行,VB標準
在C和C++里頻繁使用指針的一個重要原因是需要使用動態(tài)內(nèi)存分配,用Malloc或New來從堆棧里動態(tài)分配內(nèi)存,并得到指向這個內(nèi)存的指針。在VB里我們也可以自己用API來實現(xiàn)動態(tài)分配內(nèi)存,并且實現(xiàn)象C里的指針鏈表。
但我們不可能象C那樣直接用指針來訪問這樣動態(tài)分配的內(nèi)存,訪問時我們必須用CopyMemory將數(shù)據(jù)拷貝到VB的變量內(nèi),大量的使用這種技術(shù)必然會降低效率,以至于要象C那樣用指針來使用動態(tài)內(nèi)存根本就沒有可行性。要象C、PASCAL那樣實現(xiàn)動態(tài)數(shù)據(jù)結(jié)構(gòu),在VB里還是應(yīng)該老老實實用對象技術(shù)來實現(xiàn)。
#T#本文配套代碼中的LinkedList里有完全用指針實現(xiàn)的鏈表,它是使用HeapAlloc從堆棧中動態(tài)分配內(nèi)存,另有一個調(diào)用FindFirstUrlCacheEntry這個API來操作IE的Cache的小程序IECache,它使用了VirtualAlloc來動態(tài)分配內(nèi)存。但實際上這都不是必須的,VB已經(jīng)為我們提供了標準的動態(tài)內(nèi)存分配的方法,那就是:對象、字符串和字節(jié)數(shù)組限于篇幅,關(guān)于對象的技術(shù)這里不講,LinkedList的源代碼里有用對象實現(xiàn)的鏈表,你可以參考。字符串可以用Space$函數(shù)來動態(tài)分配,VB的文檔里就有詳細的說明。關(guān)于字節(jié)數(shù)組,這里要講講,它非常有用。我們可用Redim來動態(tài)改變它的大小,并將指向它***個元素的指針傳給需要指針的API,如下:
- dim ab() As Byte , ret As long
- '傳遞Null值A(chǔ)PI會返回它所需要的緩沖區(qū)的長度。
- ret = SomeApiNeedsBuffer(vbNullString)
- '動態(tài)分配足夠大小的內(nèi)存緩沖區(qū)
- ReDim ab(ret) As Byte
- '再次把指針傳給API,此時傳字節(jié)數(shù)組***個元素的指針。
- SomeApiNeedsBuffer(ByVal VarPtr(ab(1)))
在本文配套程序中的IECache中,我也提供了用字節(jié)數(shù)組來實現(xiàn)動態(tài)分配緩沖區(qū)的版本,比用VirtualAlloc來實現(xiàn)更安全更簡單。
2、VB.NET指針應(yīng)用突破限制
下面是一個突破VB類型檢查來實現(xiàn)特殊功能的經(jīng)典應(yīng)用,出自Bruce Mckinney的《HardCore Visual Basic》一書。
將一個Long長整數(shù)的低16位作為Interger型提取出來,
- '標準的方法,也是高效的方法,但不容易理解。
- Function LoWord(ByVal dw As Long) As Integer
- If dw And &H8000& Then
- LoWord = dw Or &HFFFF0000
- Else
- LoWord = dw And &HFFFF&
- End If
- End Function
- '用指針來做效率雖不高,但思想清楚。
- Function LoWord(ByVal dw As Long) As Integer
- CopyMemory ByVal VarPtr(LoWord), ByVal VarPtr(dw), 2
- End Function