Как конвертировать char * в BSTR? - PullRequest
19 голосов
/ 03 марта 2009

Как я могу передать символ * из C dll в VB

Вот пример кода:

void Cfunc(char *buffer,int len)
{
  BSTR buf_bstr = SysAllocString((BSTR)buffer);
  VBptr.VBfunc(buf_bstr,len);
}

Эта функция не работает, в действительности некоторые другие значения отправляются в VB, а не фактическое значение.

Может кто-нибудь предложить решение?

Ответы [ 5 ]

21 голосов
/ 03 марта 2009

Вызовите MultiByteToWideChar (), затем либо SysAllocString (), либо SysAllocStringLen ().

Не забудьте вызвать SysFreeString (), когда вам больше не нужен BSTR.

Подробно (вариант SysAllocStringLen () - он короче и быстрее):

  1. Вызовите MultiByteToWideChar () и передайте 0 в качестве пятого и шестого параметров. Он вернет количество символов в Unicode-эквиваленте строки ANSI. Помните, что строка ANSI может содержать любые символы, а не только ASCII, поэтому любые попытки вручную вычислить количество символов Unicode с учетом длины строки ANSI могут работать в некоторых случаях и не работать в других.

  2. Выделите буфер для BSTR с помощью SysAllocStringLen (). Передайте 0 в качестве первого параметра и количество символов Unicode в качестве второго параметра. Теперь у вас есть правильно выделенный, но неинициализированный BSTR. У него уже есть место для конечного нуля, и этот конечный ноль размещен правильно.

  3. Вызовите MultiByteToWideChar () второй раз, и на этот раз передайте выделенный BSTR там. Функция преобразует строку в Unicode и копирует результат в BSTR. Теперь у вас есть правильно распределенный BSTR, содержащий Unicode-эквивалент вашей строки ANSI.

  4. Передайте BSTR в VB. Наслаждайтесь.

  5. Вызовите SysFreeString () для освобождения BSTR.

21 голосов
/ 03 марта 2009

Использование _bstr_t:

_bstr_t bstrt(buffer);

Вот Святой Грааль статей преобразования строк

10 голосов
/ 12 июня 2013

Это код, который я написал, используя sharptooths answer

    int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
    BSTR bstr = SysAllocStringLen(0, wslen);
    MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
    // Use bstr here
    SysFreeString(bstr);

Обратите внимание, что использование -1 для длины строки приводит к тому, что нулевой терминатор включается в результат

2 голосов
/ 03 марта 2009

Я не возражаю против ответа Аджриана, но вот альтернатива ...

SysAllocString определен для принятия параметра типа OLECHAR *. Вы даете ему символ *. Это не одно и то же. Существуют определенные обстоятельства, когда они могут быть одним и тем же, но вы не можете зависеть от этого. Итак, прежде всего вам нужно конвертировать ваш символ * в OLECHAR *. Существует макрос под названием A2OLE, который может сделать это за вас, и в тех случаях, когда char * и OLECHAR * - это одно и то же, макрос компилируется в ничто (я думаю).

См. на этой странице для получения подробной информации об A2OLE и его друзьях.

О, и приведение вашего char * к BSTR фактически не меняет его вообще, это не BSTR и не OLECHAR *.

1 голос
/ 27 января 2014

вместо массива char *, попробуйте _tchar * array. Так как Sysallocstring принимает только символы Unicode в 32-битном приложении.

...