VB調(diào)用DLL的參數(shù)類型匹配問(wèn)題(一) 幾天前, 網(wǎng)友提到了VB中的參數(shù)與標(biāo)準(zhǔn)的C語(yǔ)言的參數(shù)的對(duì)應(yīng)關(guān)系的問(wèn)題,,說(shuō)老實(shí)話,我對(duì)次也是七竅只通了六竅,。這幾天查了些資料,,總結(jié)如下,希望能對(duì)大家編程有所幫助,。 VB調(diào)用DLL的缺省調(diào)用方式是:傳引用調(diào)用,。即VB傳一個(gè)指向參數(shù)變量的指針,DLL中便可以修改實(shí)際參數(shù)的值,。若要傳值方式,,則需要在函數(shù)申明時(shí)在參數(shù)前加上ByVal關(guān)鍵字。 下面談?wù)勛址{(diào)用的約定,。 事實(shí)上對(duì)字符串無(wú)論是否使用ByVal關(guān)鍵字,,在DLL中均可以修改傳入的參數(shù)。但,,用不用ByVal關(guān)鍵字,,還是有區(qū)別的。因?yàn)閂B與DLL接口支持兩種類型的字符串,,VB是用如下的規(guī)則來(lái)匹配類型的,,若沒用關(guān)鍵字ByVal,則傳一個(gè)VB字符串句柄(數(shù)據(jù)類型為HLSTR),,這種類型或字符串句柄只有專為VB設(shè)計(jì)的DLL才能識(shí)別,。所以,通常的DLL如果不是專門為VB設(shè)計(jì)的,,就只有用ByVal關(guān)鍵字了,。因?yàn)榧恿薆yVal關(guān)鍵字后,VB會(huì)在字符串尾加上Null字符,,即自動(dòng)將VB字符串轉(zhuǎn)換成C-style字符串,,然后將指向該串的指針傳給DLL。 VB調(diào)用DLL關(guān)于參數(shù)的匹(二) 這次談?wù)刅B與C語(yǔ)言的其他參數(shù)類型間的轉(zhuǎn)換,。包括布爾型,、16位整數(shù)、16位無(wú)符號(hào)整數(shù),、8位有和無(wú)符號(hào)整數(shù),、32位有和無(wú)符號(hào)整數(shù),、VB中Variant類型及結(jié)構(gòu)指針等。 〈布爾量〉VB和C中都定義0為“假”,,非0為“真”,,但C語(yǔ)言邏輯表達(dá)式的結(jié)果用1表示“真”,而相應(yīng)的VB返回-1做為“真”,。這是二者的區(qū)別,。 〈16位符號(hào)整數(shù)〉C語(yǔ)言中的int和short類型與VB中的integer完全對(duì)應(yīng)匹配,所以可以大膽使用,。:) 〈16位無(wú)符號(hào)整數(shù)〉VB中沒有相應(yīng)的類型,,所以就存在轉(zhuǎn)換的問(wèn)題了。關(guān)鍵是對(duì)于從32768-65535這一區(qū)間的數(shù)如何處理,。事實(shí)上可以用一個(gè)范圍更大的類型(如long)數(shù)做“中間代理”,,而達(dá)到目的。舉例如下: SignedEquivalent% = CInt( UnsighedNumber& - &h10000&) 其中UnsighedNumber&就是我們要的“代理”,。這里的訣竅是:DLL希望一個(gè)無(wú)符號(hào)的16位整數(shù),,即使VB把SighedEquivalent解釋為負(fù)數(shù),DLL也會(huì)將它解釋為我們所需要的在32768-65535間的正整數(shù),。當(dāng)然,,反過(guò)來(lái)的逆變換,如下: LongResult& = (CLng( IntegerResult%) and &h0ffff&)VB中調(diào)用DLL關(guān)于參數(shù)匹配的問(wèn)題(三) * 8位有符號(hào)和無(wú)符號(hào)整數(shù) 只要VB的無(wú)符號(hào)整數(shù)在正確的范圍內(nèi),即-128~+127或0~255之間,,就沒有任何問(wèn)題,,直接用Integer類型就可以了。 * 32位有符號(hào)整數(shù) 與VB中的Long 類型完全兼容,。真是好運(yùn)氣,。呵呵。 * 32位無(wú)符號(hào)整數(shù) 有要轉(zhuǎn)換了,,因?yàn)閂B中無(wú)相應(yīng)的類型,。這種轉(zhuǎn)換的需要主要發(fā)生在使用的變量值在 2,147,483,647 ~ 4,294,967,295范圍內(nèi)。這里可以采用與前面提到的16位無(wú)符號(hào)整數(shù)類型轉(zhuǎn)換相同的技巧,,不過(guò)要用 Currency 或 Double 數(shù)據(jù)類型做中間的“代理”,。方法相同,這里就不再羅嗦了,。 * VB中的 Variant 類型 這種類型似乎只有VB中有,,是不是有點(diǎn)太排他的感覺?所以碰到有這種類型的DLL函數(shù),,放心用吧,,那DLL肯定是專門為VB而設(shè)計(jì)的,。 * 結(jié)構(gòu)體指針 在很多場(chǎng)合,,要構(gòu)造出一個(gè)與DLL(C-Style)完全吻合的結(jié)構(gòu)體是有可能的,但,也存在走不通的情況,。下面列出了一些在結(jié)構(gòu)體中常常用到的類型,,希望對(duì)你有所幫助。 ?。茫樱簦欤澹郑拢樱簦欤?/p> BYTE長(zhǎng)度為1的字符串:string*1 16位整數(shù)Integer 32位整數(shù)Long 位域把位域里每16位合成一個(gè)整數(shù) 字符數(shù)組(定長(zhǎng))定長(zhǎng)字符串 FARPROC(函數(shù)指針)Long, 事實(shí)上VB不直接支持函數(shù)指針:) 句柄Integer LPSTR(C字符串)Long 數(shù)值數(shù)組相應(yīng)的數(shù)值數(shù)組 結(jié)構(gòu)指針Long Single或DoubleSingle或Double * VB中的 Currency 類型 事實(shí)是 C 語(yǔ)言中也沒有這種類型,, 當(dāng)可以構(gòu)造出與之相當(dāng)?shù)念愋停缦陆Y(jié)構(gòu)可以實(shí)現(xiàn): typedef struct currencystruct{ char currency_buf[8]; } Currency; * vb中的 Any 類型的應(yīng)用 這種類型申明的參數(shù)不進(jìn)行任何類型的匹配檢查,,傳遞的參數(shù)類型總是函數(shù)調(diào)用時(shí)傳進(jìn)的參數(shù)的類型,。當(dāng)然這就要求調(diào)用程序保證傳入正確的類型。實(shí)際上,,這種類型是很有用的,。例如,Windows API中很多的函數(shù)就支持多種類型的參數(shù)的調(diào)用,,一個(gè)典型的例子如下: HCURSORLoadCursor(hInstance, lpCursorName) 其中的第二個(gè)參數(shù) lpCursorName 既可以是字符串指針,,也可以是一個(gè)整數(shù)(即是光標(biāo)在資源文件中的ID)。對(duì)于這種可容許多類型的函數(shù)參數(shù),,可將相應(yīng)參數(shù)申明為 Any,。 全文到此結(jié)束了,其中也許有很多細(xì)節(jié)沒考慮周到,,有問(wèn)題歡迎提出,。 |
|