關(guān)于使用VB.NET ANY問題要點總結(jié)
我們在使用指針的時候會運到很多問題,不知道你們在編程中遇到過沒有,這里把我也前遇到的問題分享給大家一些。Any不是一個真正的類型,它只是告訴VB編譯器放棄對參數(shù)類型的檢查,這樣,理論上,我們可以將任何類型傳遞給API。Any在什么地方用呢?讓我們來看看,在VB文檔里的是怎么說的,現(xiàn)在就請打開MSDN(Visual Studio 6自帶的版本),翻到"Visual Basic文檔"->"使用Visual Basic"->"部件工具指南"->"訪問DLL和Windows API"部分,再看看"將 C 語言聲明轉(zhuǎn)換為 Visual Basic 聲明"這一節(jié)。文檔里告訴我們,只有C的聲明為LPVOID和NULL時,我們才用VB.NET ANY。實際上如果你愿意承擔(dān)風(fēng)險,所有的類型你都可以用Any。當(dāng)然,也可以如我所說,永遠不要用VB.NET ANY。
為什么要這樣?那為什么VB官方還要提供Any?是信我的,還是信VB官方的?有什么道理不用VB.NET ANY?
#T#如前面所說,VB官方不鼓勵我們使用指針。因為VB所標榜的優(yōu)點之一,就是沒有危險的指針操作,所以的內(nèi)存訪問都是受VB運行時庫控制的。在這一點上,JAVA語言也有著同樣的標榜。但是,同JAVA一樣,VB要避免使用指針而得到更高的安全性,就必須要克服沒有指針而帶來的問題。VB已經(jīng)盡***的努力來使我們遠離指針的同時擁有強類型檢查帶來的安全性。但是操作系統(tǒng)是C寫的,里面到處都需要指針,有些指針是沒有類型的,就是C程序員常說的可怕的 void*無類型指針。它沒有類型,因此它可以表示所有類型。如CopyMemory所對應(yīng)的是C語言的memcpy,它的聲明如下:
- void *memcpy( void *dest, const void *src, size_t count );
因memcpy前兩個參數(shù)用的是void*,因此任何類型的參數(shù)都可以傳遞給他。一個用C的程序員,應(yīng)該知道在C函數(shù)庫里這樣的void*并不少見,也應(yīng)該知道它有多危險。無論傳遞什么類型的變量指針給上面memcpy的void*,C編譯器都不會報錯或給任何警告。在VB里大多數(shù)時候,我們使用Any就是為了使用void*,和在C里一樣,VB也不對Any進行類型檢查,我們也可以傳遞任何類型給Any,VB編譯器也都不會報錯或給任何警告。但程序運行時會不會出錯,就要看使用它時是不是小心了。正因為在C里很多錯誤是和void*相關(guān)的,所以,C++鼓勵我們使用satic_cast
說了這么多C/C++,其實我是想告訴所有VB的程序員,在使用Any時,我們必須和C/C++程序員使用void*一樣要高度小心?!B里沒有satic_cast這種東西,但我們可以在傳遞指針時明確的使用long類型,并且用VarPtr來取得參數(shù)的指針,這樣至少已經(jīng)明確地指出我們在使用危險的指針。如程序二經(jīng)過這樣的處理就成了下面的程序:
- '使用更安全的CopyMemory,明確的使用指針!
- Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
- Sub SwapStrPtr2(sA As String, sB As String)
- Dim lTmp As Long
- Dim pTmp As Long, psA As Long, psB As Long
- pTmp = VarPtr(lTmp): psA = VarPtr(sA): psB = VarPtr(sB)
- CopyMemory pTmp, psA, 4
- CopyMemory psA, psB, 4
- CopyMemory psB, pTmp, 4
- End Sub