問(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。
前幾天在論壇中看到有一個(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。