Отправить строку BSTR, написанную в C DLL, в Excel

Я пытаюсь отправить строку BSTR, написанную в C DLL, в Excel.

Проблема:
Excel VBA получает BSTR из C DLL. Я вижу BSTR в промежуточном окне VBA и окне отладки.

Если я попытаюсь разместить эту строку в ячейке листа, значением в ячейке будет первая буква строки (S).

Кажется, что когда я пытаюсь выделить ячейку со значением BSTR, она использует указатель на начало строки. Я не знаю, как показать всю строку 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:

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.

[Excel 2010, 32 бита]


person 12avi    schedule 28.11.2016    source источник
comment
Вы возвращаете широкие символы. Запустите его через StrConv, прежде чем присваивать значение ячейке.   -  person Comintern    schedule 28.11.2016
comment
StrConv(result, vbFromUnicode) решает проблему. Однако это обходной путь, потому что если вы вызываете ReturnString() из ячейки (путем удаления модификатора закрытого доступа «= ReturnString()»), строка, возвращаемая в ячейку, также верна, как и StrConv(). Я модифицировал функцию C, чтобы она брала два BSTR из Excel и объединяла их, а затем возвращала значение в качестве теста. Возникает та же проблема. Если функция вызывается внутри ячейки, она правильно печатает полную конкатенированную строку. В VBA отображается объединенная строка (хотя и в широком формате).   -  person 12avi    schedule 29.11.2016
comment
Если я использую StrConv, объединенная строка в ячейке неверна. Части, отправленные из VBA, неверны (части C в порядке), когда отображаются в ячейке, но правильно отображаются в VBA. Опять же, если вы вызываете ту же функцию непосредственно из ячейки, объединенная строка отображается правильно. [Excel 2010, 32-разрядная версия]   -  person 12avi    schedule 29.11.2016


Ответы (1)


Я нашел решение в комментарии, просто воссоздав массив в 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. Возможно, вам придется отрегулировать размер самостоятельно. Надеюсь, это поможет!

person Quincy Hsieh    schedule 02.07.2020