API中VB字符串作參數(shù)傳遞的本質(zhì)論

字號(hào):

問(wèn)題背景:
     前幾天在論壇中看到有一個(gè)提問(wèn)的問(wèn)題,內(nèi)容是:
     模塊中的代碼:
     Option Explicit
     Public Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long’聲明獲取計(jì)算機(jī)名的API函數(shù)
     窗體中的代碼:
     Option Explicit
     Private Sub Command1_Click()
     Dim computername As String
     Dim length As Long
     length = 255
     str = String(length, 0)
     GetComputerName computername, length
     Debug.Print computername,
     End Sub
     以上程序的功能是獲取計(jì)算機(jī)名。
     大家看上面API中的lpBuffer這個(gè)形參被聲明為Byval(傳值)方式。那么在調(diào)用之后API函數(shù)卻可以通過(guò)computername這個(gè)實(shí)參傳回計(jì)算機(jī)名,那么形參不是被聲明為傳值調(diào)用方式嗎?即形參值的改變不會(huì)影響到實(shí)參,可是這里調(diào)用API函數(shù)后卻可以通過(guò)實(shí)參返回值,這是到底是什么原因呢?
     相關(guān)知識(shí):
     大家都知道,VB中沒(méi)有C語(yǔ)言中的指針類型。C語(yǔ)言中只有字符數(shù)據(jù)類型,即字符變量只能存放一個(gè)字符,而沒(méi)有字符串變量,它操作字符串是通過(guò)字符型指針來(lái)實(shí)現(xiàn)的,它的特點(diǎn)是通過(guò)’\0’來(lái)判斷字符是否結(jié)束的。而VB有字符串變量類型,一種變長(zhǎng),一種是定長(zhǎng)的。并且VB字符串具體自動(dòng)保護(hù)功能。
     例如:dim str as string * 6
     str=”abcdef”
     debug.print str’那么將顯示abcdef
     str=”abcdefghijklmnopq”
     debug.print str’還顯示abcdef,說(shuō)明它具有保護(hù)功能,將超過(guò)的字符截掉
     在VB中使用的字符是一種叫做BSTR格式的字符串指針類型。
     字符個(gè)數(shù)描述符由VB來(lái)使用,BSTR指針直接指向第一個(gè)字符。
     因?yàn)榇蠖鄶?shù)API函數(shù)是用C或C++來(lái)編寫(xiě)的,在C/C++(API)中使用叫做LPSTR類型的指針。
     字符串變量X的地址與實(shí)際字符串的地址不同,也就是說(shuō)字符X變量中實(shí)際上是存放的字符串的首地址這一點(diǎn)是和C/C++相同的。其實(shí)圖中descriptor這個(gè)描述符就是C中的字符串指針地址。當(dāng)BSTR指針在忽略字符個(gè)數(shù)描述前綴的情況下是與LPSTR指針是相同的,在調(diào)用API時(shí)可以將BSTR以傳值方式傳遞給API。