VB6 - Как передать строки в DLL, написанную на C, через файл .tlb - PullRequest
2 голосов
/ 08 марта 2011

Я работаю над графическим интерфейсом, написанным на VB6, где мне нужно вызывать функцию, содержащуюся в определенной DLL, написанной на C. Из-за известного ограничения Мне пришлось реализовать трюк , что позволяет мне неявно загружать эту DLL.

Это возможно при создании файла IDL, скомпилировать его с MIDL и ссылаться на полученный файл .tlb в проекте VB6.

Проблема в том, что строки VB6 и массивы C из char не совпадают, поэтому я не могу передать (и получить обратно) их в DLL.

Прототип функции C:

int __stdcall myFunc(char filename_in[], char filename_out[], char ErrMsg[]);

Что я должен записать в файл IDL и как мне вызвать его из VB6?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 08 марта 2011

Вы должны использовать BSTR, чтобы использовать строки, совместимые с VB6. Это стандартный тип строки COM, он хранит строки Unicode в кодировке utf-16, как и Win32 API.

 int __stdcall myFunc(BSTR filename_in, BSTR filename_out, BSTR* ErrMsg);

Вы можете привести входные аргументы к WCHAR * напрямую, используя WideCharToMultiByte (), если вам нужно преобразовать в char * (лучше избегать). Используйте SysFreeString, если *ErrMsg не равно NULL, чтобы освободить существующую строку перед ее назначением. Используйте SysAllocString для выделения строки ErrMsg. Это также должна быть строка utf-16, MultiByteToWideChar () при необходимости снова конвертировать из char *. Или используйте строковый литерал с префиксом L, например L "Упс".

2 голосов
/ 08 марта 2011

VB6 не имеет проблем при использовании функций stdcall с параметрами строк ANSI.Просто используйте [in] LPSTR filename_in в IDL, и среда выполнения автоматически выполняет преобразование ANICODE <-> ANSI.

"Волшебство" работает и для [out] параметров.

0 голосов
/ 08 марта 2011

Благодаря GSerg и wqw Я нашел решение этой проблемы:

В файле IDL массив символов должен быть объявлен как LPSTR, поэтому прототип функции выглядит следующим образом:

int _stdcall myFunc(LPSTR file_name_in, LPSTR file_name_out, LPSTR ErrMsg)

обратите внимание, что ErrMsg объявляется точно так же, как и другие массивы, даже если он содержит выходное сообщение (читаемое на стороне VB6).

На стороне VB6 строки должны быть выделены как:

Dim file_name_in As String * 256
Dim file_name_out As String * 256
Dim ErrMsg As String * 256

При этом эти строки выделяются с ограниченным размером 256, что делает их совместимыми с массивами символов в C DLL.

Надеюсь, это поможет кому-то еще.

С уважением,

G.B.

...