четверг, 22 ноября 2012 г.

Проблема в C++ со строками

Проблема: не могу понять в чем разница между BSTR, LPSTR, LPWSTR, LPTSTR и прочими строками в С++.

Решение:

  • CHAR - это typedef на char - обычный байт от 0 до 255 или от -128 до +128
  • WCHAR - это typedef на wchar_t - "широкий" символ, которого по стандарту должно быть гарантировано достаточно для хранения любой буквы любого алфавита. На практике это не так, ибо в GNU-шных компиляторах вместимость wchar_t - 32 бита (4 байта). В ms-компиляторах - 16 бит, чего уж точно не хватает на все алфавиты, поэтому используются свои извращения. Важно понимать что WCHAR - это не тот же самый Unicode
  • TCHAR - если при сборке задан #define UNICODE, то будет преобразован в WCHAR, если нет - то в CHAR. #define UNICODE по факту вносит путаницу, ибо как было сказано - wchar_t - не является юникодом. При использовании TCHAR - все системные вызовы так же перейдут на широкие символы если будет задан #define UNICODE. Для того, чтобы и c-style функции перешли на широкие символы - необходимо использовать те, что с префиксом _tcs (_tcslen, _tcscat, _stprintf). std-контейнеры не переходят на широкие символы автоматически. Однако это легко решается методами вроде: 
#ifdef UNICODE
#define std::string std::wstring
#endif
  • Постфикс STR - признак массива CHAR/TCHAR/WCHAR-ов. Сам по себе не используется
  • Префиксы LP, P - признак указателя на массив CHAR/TCHAR/WCHAR-ов, в зависимости от названия (например, LPWSTR - указатель на массив WCHAR-ов, LPTSTR - TCHAR-ов, LPSTR - просто CHAR-ов). LP - "длинный" указатель (Long Pointer), не знаю что значит. P - обычный указатель (Pointer)
  • BSTR - по факту всегда является LPWSTR. Используется для общения с COM-интерфейсами и только с ними. Потому как там все только на широких строках. Для операции с ним есть ATL-класс CComBSTR, предоставляющий инструменты конвертации. Так же стоит иметь в виду вызовы ::SysAllocString и ::SysFreeString.
Раздел MSDN, который поможет не умереть с тоски: Unicode and Character Set Functions (Windows)

Комментариев нет:

Отправить комментарий