Excel VBA未正确设置单元格值到BSTR

时间:2016-11-28 10:08:55

标签: c vba excel-vba dll bstr

我正在尝试将用C DLL编写的BSTR字符串发送到Excel,但在VBA中有问题。

我会感激地收集任何帮助,因为我搜索了之前关于BSTR的主题和博客,但无法找到解决其他明显问题的方法。

问题: Excel VBA正确地从C DLL接收BSTR。我可以在VBA中间窗口和调试窗口中看到BSTR。

但是,如果我尝试将此字符串分配给工作表中的单元格,则单元格中的值只是字符串的第一个字母(" S")。

在我看来,当我尝试分配具有BSTR值的单元格时,它只使用指向String开头的指针。我不知道如何显示整个BSTR字符串。

C代码:

BSTR _stdcall ReturnString(void)
{
    return SysAllocString(L"String From DLL");
}

VBA代码:

Private Declare Function ReturnString Lib "C:\ex4dl.dll" () As String   

Sub test_sub()
    Dim result As String
    result = ReturnString()
    Range("B1").Value = result
    Debug.Print result
End Sub

从我的评论开始,如果直接从单元格调用C函数并且StrConv()不能作为完整修复,则C函数正常工作,下面是连接字符串的C代码。

C代码:

BSTR _stdcall ReturnStringTwo(BSTR stringOne, BSTR stringTwo )
{
    BSTR finalString;
    int buffer_len = _snwprintf(0,0,L"The strings that was passed (%s) and (%s)", stringOne, stringTwo);
    finalString = SysAllocStringLen(0, buffer_len);
    _snwprintf(finalString,buffer_len,L"The strings that was passed (%s) and (%s)", stringOne, stringTwo);
    return finalString;
}

VBA代码:

Private Declare Function ReturnStringTwo Lib "C:\ex4dl.dll" (ByVal stringOne As String, ByVal stringTwo As String) As String

Sub test_sub()
Dim iString As String
Dim iStringTwo As String
Dim one As String
Dim two As String
one = "One"
two = "Two"

iString = ReturnString()
iStringTwo = ReturnStringTwo(one, two)
Range("B1").Value = StrConv(iString, vbFromUnicode) ' Works ok with the C only string'
Range("B2").Value = StrConv(iStringTwo, vbFromUnicode) 'Does not work correctly.  The cells value is: "The strings that was passed (?e) and (?o)"'

End Sub

如果直接从单元格调用,这两个函数都可以正常工作,但如果从VBA分配给cell.value则不能正常工作。

[Excel 2010 32bit]

1 个答案:

答案 0 :(得分:0)

我在注释中找到了解决方案,只需在VBA中重新创建一个数组即可,并在输出中将StrConv(result,vbFromUnicode)转换为值。那解决了问题。这是我的VBA代码:

Public Function apiCall(x As Range) As Variant
    Dim selectedArray As Variant
    selectedArray = x.Value2
    Dim dll_output(32, 32) As String
    Dim res(32, 32) As String
    v = callDllFunc(selectedArray, dll_output)
    For j = LBound(dll_output, 2) To UBound(dll_output, 2)
        For i = LBound(dll_output, 1) To UBound(dll_output, 1)
        res(i, j) = StrConv(dll_output(i, j), vbFromUnicode)
        Next
    Next
    apiCall = res
End Function

请注意,上面的代码只是创建了一个32x32的Double String数组。您可能需要自己调整大小。我希望这会有所帮助!