我正在尝试将用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]
答案 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数组。您可能需要自己调整大小。我希望这会有所帮助!