1

尝试了一些API编程,遇到了AVICAP32.dll的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
4

1 回答 1

0

我首先要说我对这个主题知之甚少(封送数据可能是一个很深的主题),但我认为字符串的默认封送处理(MSDN) 可能会对您有所帮助。向下滚动到显示Fixed-Length String Buffers的部分。据此,当一个字符串被编组到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

lpszName从变为。String_ StringBuilder显然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? .

于 2013-07-10T15:34:36.310 回答