Какой код лучше для преобразования параметров BSTR в ANSI в C/C++?

До сих пор я обнаружил, что могу преобразовывать входящие BSTR в ANSI двумя (из многих?) Способами, и мне любопытно узнать, является ли один «лучше», чем другой, в отношении скорости/эффективности и т. д.

Некоторое время я использовал макросы USES_CONVERSION и W2A, например.

BSTR __stdcall F(BSTR p1, BSTR p2 ) {
    USES_CONVERSION;

    LPSTR sNum1 = W2A( p1 );
    LPSTR sNum2 = W2A( p2 );

Однако недавно я наткнулся на другую технику:

BSTR __stdcall F(BSTR p1, BSTR p2 ) {
    long amt = wcstombs( NULL, p1, 1 );
    sNum1 = (char *) malloc( amt ); 
    wcstombs( sNum1, p1, amt );
    *(sNum1 + amt) = '\0';

    amt = wcstombs( NULL, p2, 1 );
    sNum2 = (char *) malloc( amt ); 
    wcstombs( sNum2, p2, amt );
    *(sNum2 + amt) = '\0';

Теперь я согласен с вами, это более многословно и имеет два вызова wcstombs, но, насколько я знаю, макросы USES_CONVERSION и W2A могут скрывать всевозможные развлечения и игры.

Какой код более эффективный/быстрый? Или есть другой метод, который я мог бы использовать, чтобы сделать эту работу лучше?


person bugmagnet    schedule 23.02.2009    source источник
comment
Второй код имеет неопределенное поведение, поскольку он записывает за пределы выделенного буфера.   -  person Rob Kennedy    schedule 23.02.2009


Ответы (4)


Обратите внимание на утвержденный ответ Ника, который, хотя и является правильным, имеет ту же проблему, что и документация MSDN, описывающая макросы.

Проблема в том, что некоторые макросы, такие как тот, что указан @Nick - COLE2A, на самом деле не существуют.

Однако дальше на странице MSDN есть некоторый текст, который подсказывает вам этот факт и позволяет вам определить правильный макрос!

Текст указан в таблице под следующим текстом:

Есть несколько важных различий между старыми макросами преобразования строк и новыми классами преобразования строк:

В столбце Новые классы преобразования ATL 7.0.

Что говорит:

OLE всегда эквивалентен W

Таким образом, макрос в примере @Nick на самом деле CW2A

person Peter Nimmo    schedule 04.03.2010

Из MSDN:

[...] Рекомендуемый способ преобразования в строки BSTR и из них — использовать ссылку класс CComBSTR. Чтобы преобразовать в BSTR, передайте существующую строку конструктору CComBSTR. Для преобразования из BSTR используйте COLE2[C]DestinationType[EX], например COLE2T.

Со страницы CComBSTR:

[...] Класс CComBSTR предоставляет ряд членов (конструкторов, операторов присваивания и операторов сравнения), которые принимают в качестве аргументов строки ANSI или Unicode. Версии ANSI этих функций менее эффективны, чем их аналоги Unicode, поскольку временные строки Unicode часто создаются внутри. Для эффективности по возможности используйте версии Unicode.

person dirkgently    schedule 23.02.2009

Примечание:

Если вы используете макросы ATL, например: COLE2[C]DestinationType[Ex] (что вам, вероятно, следует), убедитесь, что вы используете версии 'C', а не неконстантные версии, как вы написали. Они могут быть эквивалентны для явных преобразований BSTR->ASCII (например, COLE2A), но для преобразований, где не требуется фактическое преобразование (например, COLE2T при компиляции для UNICODE), версии 'C' могут расширяться до noops, тогда как не -Версии 'C' будут по-прежнему копироваться, если исходная строка является константной (поскольку вы заявляете, что вам нужна неконстантная результирующая строка).

Также следует отметить:

Новые макросы ATL7 не всегда требуют USES_CONVERSION, однако они выделяют временные объекты r-value, тогда как старые макросы используют _alloca. Это может быть или не быть важным, в зависимости от вашего использования (например, НЕ используйте старые макросы в цикле, который выполняется большое количество раз, вы можете взорвать стек, делая это).

person Nick    schedule 23.02.2009

Прошло много времени с тех пор, как я делал что-либо с COM или BSTR, но я предлагаю перестать относиться к BSTR как к чему-то особенному. Относитесь к ним как к указателю на строку с широким символом, заканчивающуюся нулем... если вы это сделаете, может быть проще преобразовать их в ANSI. проверьте Полное руководство Эрика по семантике BSTR...

person nabiy    schedule 24.02.2009