在VB中調用Windows API的注意事項
發表于:2007-07-14來源:作者:點擊數:
標簽:
朱運喜 Visual Basic ( VB )作為一種高效編程環境,它封裝了部分 Windows API函數,但也犧牲了一些API的功能。調用API時稍有不慎就可能導致API編程錯誤,出現難于捕獲或間歇性錯誤,甚至出現程序崩潰。要減少API編程錯誤,提高VB調用API時的 安全 性,應重點
朱運喜
Visual Basic (
VB)作為一種高效編程環境,它封裝了部分
Windows API函數,但也犧牲了一些API的功能。調用API時稍有不慎就可能導致API編程錯誤,出現難于捕獲或間歇性錯誤,甚至出現程序崩潰。要減少API編程錯誤,提高VB調用API時的
安全性,應重點注意下列八個問題:
(1)指定“Option Explicit”
編程前最好將VB編程環境中的“Require Variable Declaration(要求變量申明)項選中。如果該項未被指定,任何簡單的錄入錯誤都可能會產生一個“Vari
ant”變量,在調用API時,VB對該變量進行強制轉換以避免沖突,這樣一來,VB就會為字符串、長整數、整數、浮點數等各種類型傳遞NULL值,導致程序無法正常運行。
(2)注意VB整數和Win32整數的區別
在VB環境下,涉及到的所有integer(整型數),都是16位,而一旦涉及C/C++Win32文檔時,則是32位,閱讀與Windows API函數或與32位動態鏈接庫有關的資料或應用程序時,尤其要注意分析理解環境背景,以利于分清數據類型和數據結構,正確地聲明API函數。
(3)減少和避免使用As Any
雖然用As Any的方法聲明庫,可使Windows API函數能接受多種類型的參數,但更嚴重的是,即使是一個很小的錯誤,比如遺漏類型標識符或錯誤地使用了ByVal關鍵字,都可能導致系統崩潰或很難發現的其他數據錯誤。
(4)注意檢查參數類型
API錯誤中,除了因遺漏ByVal關鍵字導致的錯誤外,大約有50%是因為聲明中有不正確的參數類型。在Win32環境下,無論是8位、16位,還是32位數值變量都是以32位傳遞,如果同時使用,則很難發現其中錯誤。如果聲明的參數類型不同,被VB視為Variant傳遞給API函數,會出現“錯誤的DLL調用規范”的消息。
(5)勿忘ByVal,確保函數聲明的完整性
ByVal是“按值”調用,參數傳遞時,不將指向DLL的指針傳遞給參數變量本身,而是將傳遞參數值的一份拷貝傳遞給DLL。比如傳遞字符串參數時,VB與DLL之間的接口支持兩種類型的字符串,如未使用ByVal關鍵字,VB將指向DLL的函數指針傳遞給一個OLE2.0字符串(即BSTR數據類型),而Windows API函數往往不支持這種數據類型,導致錯誤。而使用ByVal關鍵字后VB將字符串轉變換成C語言格式的“空終止”串,被API正確使用。
(6)重新檢查函數名
在Win16環境下,API函數的名字不要求區分大小寫,而在Win32環境下,則有此要求。在一個DLL函數里找不到聲明的函數時,有必要檢查一下函數名,對于管理字符串的函數,是否遺漏了A和W前綴。
(7)預先初始化字符串,以免造成沖突
如果API函數要求一個指向緩沖區的指針,以便從中載入數據,而此時傳遞的是字符串變量,應該先初始化字符串長度。因為API無法知道字符串的長度——API默認已為其分配有足夠的長度。沒有初始化字符串,分配給字符串的緩沖區有可能會不足,API函數將有可能在緩沖區末尾反復改寫,內存里字符串后面的內容將會改寫得一塌糊涂。程序表現為突然終止或間歇性錯誤。
(8)跟蹤檢查參數、返回類型和返回值
VB具有立即模式和單步調試功能,利用這個優勢,確保函數聲明的類型明確(API不返回Variant類型),通過跟蹤和檢查參數的來源及類型,可以排除參數的錯誤傳遞。許多API函數都有返回結果,指出自己是否執行成功。你若要對返回結果進行
測試,用VB的Err對象的LastDllError方法可查閱這些信息,對錯誤可針對API函數調用,取回API函數GetlastError的結果,以修改聲明,達到正確調用API函數之目的。
原文轉自:http://www.anti-gravitydesign.com