Передача BSTR из C ++ DLL-функции в приложение VB6 - PullRequest
1 голос
/ 26 мая 2011

У меня есть этот код в моем приложении VB6:

Private Declare Function FileGetParentFolder Lib "Z-FileIO.dll" _
(ByVal path As String) As String

Output.AddItem FileGetParentFolder(FileText.Text)

Выход - список, FileText - текстовое поле, содержащее путь к файлу. Моя C ++ DLL содержит эту функцию:

extern "C" BSTR ZFILEIO_API FileGetParentFolder(Path p)
{
    try {
        return SysAllocString(boost::filesystem::path(p).parent_path().c_str());
    } catch (...) {
        return SysAllocString(L"");
    }
}

, где Path - это typedef'd как LPCSTR. Аргумент входит в мою DLL отлично, но что бы я ни пытался передать обратно, приложение VB6 показывает только мусор. Я попробовал несколько различных методов с SysAllocStringByteLength, приведя аргумент SysAllocString к LPCWSTR и другие варианты. Либо я вижу только первую букву строки, либо вижу только Y с точками, но не настоящую строку. Кто-нибудь знает, каков настоящий метод создания и передачи действительных BSTR из C ++ в VB6?

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Если вы настаиваете на использовании сигнатуры функции, вам нужно подготовить настраиваемую библиотеку типов для VB6, которая включает в себя

[dllname("Z-FileIO.dll")]
module ZFileIO
{
    [entry("FileGetParentFolder")]
    BSTR FileGetParentFolder ([in] LPWSTR path);
};

В Declare s параметры типа As String автоматически преобразуются в строку ANSI, т.е. LPSTR. Единственный способ передать / получить строку Unicode (LPWSTR или BSTR) - использовать объявление функции typelib API.

Кроме этого, вы всегда можете использовать As Long params в объявлении и ожидать LPWSTR s, но тогда потребителю придется заключать строки в StrPtr при каждом вызове функции API.

2 голосов
/ 26 мая 2011

Надеюсь, это укажет вам правильное направление.Из памяти ...

VB6 использует COM BSTR (2-байтовые строки широких символов) для внутреннего использования, но при связи с внешними DLL он использует одно- или многобайтовые строки.(Возможно, UTF-8, но я точно не помню.) Ваш путь typedef к LPCSTR - это строка ANSI, и поэтому вы можете получить ее правильно.Возвращаемое вами значение - строка широких символов, но VB ожидает строку ANSI.Вам нужно будет использовать WideCharToMultiByte для преобразования вашего возвращаемого значения перед его возвратом.

Кажется немного странным, что VB выполняет это неявное преобразование, но это так.(Насколько я помню.)

...