在一个C写的API函数中有一个函数是用来返回配置文件的名称和个数的函数。定义是这样的:
int GetConfigFileInfo(int * return_config_count, char ** return_config_names[]);在C中的调用是这样的:
int configCount = 0;
char ** configNames = NULL;
GetConfigFileInfo(configCount, configNames);而我在VB.NET中是如下声明和调用的:
Declare Ansi Function GetConfigFileInfo Lib "myconfig.dll" (ByRef configCount As Integer, ByRef configNames() As String) As IntegerDim configCount As Integer
Dim configNames() As StringGetConfigFileInfo(configCount, configNames)但是不管有多少个配置文件,结果configNames数组的长度总为1,并且总是返回第一个配置文件名称。如果在Declare时用ByVal声明这个字符串数组参数,则调用时便会出错。请问在VB.NET中能够使用这样的API函数吗?应该如何声明使用?非常感谢!

解决方案 »

  1.   

    问题终于解决了。因为VB无法直接返回字符串数组,所以在调用Dll的时候要传入IntPtr指针,然后根据返回的指针和相对的偏移量才能得到所有的字符串数组的值。 Declare Ansi Function GetConfigFileInfo Lib "myconfig.dll" (ByRef configCount As Integer, ByRef configNamesPtr As IntPtr) As Integer Public Function Test(ByRef theConfigs As String()) As Boolean
    Dim tResult As Boolean
    Dim tPtr As IntPtr
    Dim tCount As Integer tResult = GetConfigFileInfo(tCount, tPtr)
    If tResult Then
    theConfigs = GetStringsFromPP(tPtr, tCount)
    End If Return tResult
    End Function '从类似 vir_char ** var[] 类型函数参数的返回的数据中获得字符串数组
    Public Function GetStringsFromPP(ByVal thePtr As IntPtr, ByVal theCount As Integer, Optional ByVal theEncoding As String = "UTF-8") As String()
    Dim tResult As String()
    ReDim tResult(theCount - 1) Dim tPtrInt As Integer
    Dim tPPAddr As IntPtr
    Dim tPPtr As IntPtr
    Dim tPPPtr As IntPtr Dim tEncoding As Encoding tEncoding = Encoding.GetEncoding(theEncoding)
    tPtrInt = thePtr.ToInt32 For i As Integer = 0 To theCount - 1
    '从返回的字符数组指针的指针的值tPtrInt加上偏移量,得到第i个字符串起始字符的指针的地址
    tPPAddr = New IntPtr(tPtrInt + IntPtr.Size * i)
    '从该指针获得的值就是第i个字符串的起始字符的指针
    tPPtr = Marshal.ReadIntPtr(tPPAddr) '由于编码不确定,所以按字节方式读取,直至遇到'\0'(注意不能包含'\0')
    Dim tBytes As Byte()
    Dim j As Integer While Marshal.ReadByte(tPPtr, j) <> 0
    ReDim Preserve tBytes(j)
    tBytes(j) = Marshal.ReadByte(tPPtr, j)
    j += 1
    End While '然后通过确定编码获得字符串
    tResult(i) = tEncoding.GetString(tBytes)
    Next Return tResult
    End Function