12avi
12avi

Reputation: 495

Send a BSTR string written in a C DLL to Excel

I am trying to send a BSTR string written in a C DLL to Excel.

Problem:
Excel VBA receives the BSTR from the C DLL. I can see the BSTR in the VBA Intermediate window and debug window.

If I try to allocate this string to a cell within a sheet, the value within the cell is the first letter of the string ("S").

It seems that when I try to allocate a cell with the value of the BSTR, it is using a pointer to the start of the String. I do not know how to show the whole BSTR string.

C Code:

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

VBA Code:

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

Following on from my comment that the C function works ok if called directly from a cell and StrConv() not working as a complete fix, below is the C code for the concatenated strings.

C Code:

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 Code:

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

Both functions work if called directly from a cell, but not if allocated to a cell.value from VBA.

[Excel 2010 32bit]

Upvotes: 2

Views: 993

Answers (1)

Quincy Hsieh
Quincy Hsieh

Reputation: 304

I found the solution in the comment by simply re-creates an array in VBA with StrConv(result, vbFromUnicode) converting value in the output. That solved the problem. Here is my VBA code:

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

Note that the code above simply creates an 32x32 double String array. You might need to adjust the size by yourself. I hope that this helps!

Upvotes: 1

Related Questions