为什么capGetDriverDescription接受缓冲区作为值类型而不是引用类型?

时间:2013-07-10 14:29:52

标签: vb.net api dll

尝试一些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而不是{{1当然,它应该是一个参考,因为从函数返回后存储我需要的信息。但是在这个函数中,它是一个值类型,它工作正常! 即使我试图将其更改为ByRef,但应用程序没有运行! 我错过了什么知识?这个缓冲区如何在传递值类型时存储我的信息?

这是代码调用函数以获取可用网络摄像头的方法:

ByVal

1 个答案:

答案 0 :(得分:0)

我首先要说的是我对这个主题知之甚少(编组数据可能是一个很深的主题),但我认为 Default Marshaling for Strings (MSDN)可能会对你有所帮助。向下滚动到固定长度字符串缓冲区的部分。根据这个,当一个字符串被封送到API时,即使传递了byRef,它也不能被被调用者修改。

我没有测试过,但是根据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

lpszNameString更改为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?