2013-07-10 25 views
1

嘗試一些API編程,我遇到了AVICAP32.dll的capGetDriverDescription功能的問題:爲什麼capGetDriverDescription接受緩衝區作爲值類型而不是引用類型?

Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _ 
    ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, _ 
    ByVal cbVer As Integer) As Boolean 

據我所知,lpszName參數是讓司機描述的緩衝區,而我讀的地方緩衝區應該作爲參考類型傳遞(ByRef而不是ByVal),當然它應該是一個參考,因爲從函數返回後存儲我需要的信息。但是在這個函數中,它是一個值類型,它工作正常! 即使我試圖將其更改爲ByRef,但應用程序沒有運行! 我缺少什麼知識?這個緩衝區在傳遞值類型時如何存儲我的信息?

這是怎樣的代碼調用函數來獲取可用的攝像頭:

Private Sub LoadDeviceList() 
    On Error Resume Next 
    Dim strName As String = Space(100) 
    Dim strVer As String = Space(100) 
    Dim bReturn As Boolean 
    Dim x As Integer = 0 

    Do 
     bReturn = capGetDriverDescriptionA(x, strName, 100, strVer, 100) 
     If bReturn Then 
      lst1.Items.Add(strName.Trim) 
     End If 
     x += 1 
     Application.DoEvents() 
    Loop Until bReturn = False 
End Sub 

回答

0

我會說,我不知道很多關於這個問題(數據編組可以是一個深度的主題)開始,但我認爲Default Marshaling for Strings(MSDN)可能會對您有所幫助。向下滾動至固定長度字符串緩衝區。據此,當一個字符串封送到API時,即使通過了Ref,它也不能被被調用者修改。

我沒有測試過,但根據MSDN例如,要得到一個值從功能回來,定義將成爲

Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _ 
ByVal lpszName As StringBuilder, ByVal cbName As Integer, ByVal lpszVer As String, _ 
ByVal cbVer As Integer) As Boolean 

String更改lpszNameStringBuilder。顯然StringBuilder將作爲一個緩衝區來從函數中獲取字符串。

那麼你會打電話給你的功能,像這樣,

StringBuilder sb = new StringBuilder(256) 
capGetDriverDescription(Driver, sb, sb.Capacity + 1, .... 
return sb.ToString() 

我發現了一個非常類似的問題,How do I import and call unmanaged C dll with ANSI C string "char *" pointer string from VB.NET?

+0

感謝您的回答,我使用的示例不使用任何StringBuilder。它只是在函數中使用正常字符串,因爲我粘貼了我的問題。此示例在調用函數時也使用普通字符串。但這個代碼仍然有效!順便說一下,我應該從哪裏開始學習使用dll? –

+0

對不起,我沒有足夠的聲望來投票你的答案 –

+0

是的,它將使用普通的字符串,你只需要使用StringBuilder來獲得結果。我不確定是否有任何地方可以學習這個東西(除Stack Overflow之外),但是http://pinvoke.net/是查找流行函數和數據結構的.NET定義的絕佳網站。 – Kratz

相關問題