如何从VBA应用程序调用C DLL并返回数组?

时间:2018-07-29 12:00:31

标签: c arrays vba

我正在开发一个VBA应用程序,该应用程序通过C DLL读写串口。在下面的代码中,我设法以字符串形式将值返回到VBA代码中。

我想做的是在DLL中调用该函数,并将返回的值插入到数组中。我也不想在我回来后使用split函数将字符串解析为and数组,因为我的VBA实现无法访问该函数。

C DLL函数

void FAR PASCAL RxReadResponse(char* Response)
{
    char TempChar; //Temporary character used for reading
    char SerialBuffer[100];//Buffer for storing Rxed Data
    DWORD NoBytesRead;
    int i = 0;
    char buf [20];
    char bufFull [256];
    long num;
    long streamLenght;
    do
     {
          ReadFile( hComm,           //Handle of the Serial port
                    &TempChar,       //Temporary character
                    sizeof(TempChar),//Size of TempChar
                    &NoBytesRead,    //Number of bytes read
                    NULL);


          SerialBuffer[i] = TempChar;// Store Tempchar into buffer
          sprintf(buf,"%x",TempChar& 0xFF);
          strcat(bufFull, buf);

          if(i==0)
           {
              num = (int)TempChar;
              streamLenght = num + 4;
           }

          i++;
     }
    while (i < streamLenght);

    lstrcpy (Response, bufFull);
}

VBA声明

Declare Function RxReadResponse Lib "CDLL" (ByRef rxRead As String) As String

VBA按钮单击

Sub Button2_EventClick()
Dim This As Object : Set This = Button2

    Dim s

    s = RxReadResponse

    EditBox6.Text = s


End Sub 

返回的字符串

0FB34CB45AB24BB45A4CB45AB24BB45A

VBA中所需的结果

s(0) = OF
s(1) = B3
s(2) = 4C
     .
     .
     .
s(16) = 5A

我需要做些什么?

2 个答案:

答案 0 :(得分:0)

参考我的一个旧项目,我做了以下工作(翻译成您的项目)。

在C中:

char * __stdcall RxReadResponse(char* Response)
{
    //....
    return Response;
}

在VBA中:

Declare Function RxReadResponse Lib "CDLL" ( _
        ByVal Response As String _
) As String

Sub Button2_EventClick()
    Dim s As String
    s = String(256, vbNullChar) 'string (storage) of 256 null chars

    s = RxReadResponse (s)
    '....
End Sub 

我希望这可以在VBA方面为您提供帮助。

至于C部分,您现在返回一个字符串,但似乎要返回原始字节。您可以通过将TempChar放在Response[i]中而无需使用sprintf来做到这一点。只需将Response视为字节缓冲区,而不是VBA字符串类型。

答案 1 :(得分:0)

VBA可以直接将String分配给字节数组。如果dll调用返回的字符串正确,则只需重新分配它即可。

Private Sub Example()
    Dim returned As String
    returned = "0FB34CB45AB24BB45A4CB45AB24BB45A"
    Dim cast() As Byte
    cast = returned
    Dim i As Long
    For i = 0 To UBound(cast)
        Debug.Print cast(i)
    Next
End Sub

请注意,您可能必须检查一下编组程序是否将ASCII返回的字符转换为宽字符,但是如果是这种情况,则可以调用StrConv将其转换回原来的字符,也可以直接跳过字节数组。