Как преобразовать char * в BSTR?
Как передать char * из C dll в VB
Вот пример кода:
void Cfunc(char *buffer,int len)
{
BSTR buf_bstr = SysAllocString((BSTR)buffer);
VBptr.VBfunc(buf_bstr,len);
}
Эта функция не работает. В действительности некоторые другие значения отправляются в VB, а не в фактическое значение.
Может ли кто-нибудь предложить решение?
Ответы
Ответ 1
Вызовите MultiByteToWideChar(), затем либо SysAllocString(), либо SysAllocStringLen().
Не забудьте вызвать SysFreeString(), когда вам больше не нужен BSTR.
Подробно (вариант SysAllocStringLen() - он короче и быстрее):
-
Вызовите MultiByteToWideChar() и передайте 0 как пятый и шестой параметры. Он вернет количество символов в эквиваленте Unicode строки ANSI. Помните, что строка ANSI может содержать любые символы, а не только ASCII, поэтому любые попытки вручную подсчитать количество символов Unicode, учитывая длину строки ANSI, могут работать в некоторых случаях и не работать в других.
-
Выделите буфер для BSTR с помощью SysAllocStringLen(). Передача 0 в качестве первого параметра и количество символов Юникода в качестве второго параметра. Теперь у вас есть правильно выделенный, но неинициализированный BSTR. Он уже имеет место для конечного нуля, и этот конечный ноль правильно помещен.
-
Второй раз вызовите MultiByteToWideChar() и на этот раз передайте выделенный BSTR. Функция преобразует строку в Юникод и копирует результат в BSTR. Теперь у вас есть зарезервированный BSTR, содержащий эквивалент Unicode вашей строки ANSI.
-
Передайте BSTR в VB. Наслаждайтесь.
-
Вызовите SysFreeString(), чтобы освободить BSTR.
Ответ 2
Используйте _bstr_t
:
_bstr_t bstrt(buffer);
Вот священный Грааль статей преобразования строк
Ответ 3
Это код, который я написал с помощью 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 для длины строки приводит к тому, что нулевой ограничитель включен в результат
Ответ 4
У меня нет возражений против айрианского ответа, но вот альтернатива...
SysAllocString определяется как параметр типа OLECHAR *. Вы даете ему char *. Это не одно и то же. Существуют определенные обстоятельства, когда они могут быть одним и тем же, но вы не можете зависеть от этого. Поэтому прежде всего вам нужно преобразовать ваш char * в OLECHAR *. Существует макрос A2OLE, который может сделать это для вас, и в тех случаях, когда char * и OLECHAR * - одно и то же, макрос не компилируется (я думаю).
Подробнее о A2OLE и его друзьях см. эту страницу.
О, и отличать ваш char * к BSTR фактически не меняет его вообще, это не BSTR и OLECHAR *.
Ответ 5
вместо массива char *, попробуйте _tchar * array.Because Sysallocstring принимает только символы Unicode в 32-битном приложении.