Правильный способ кроссплатформенного преобразования из std::string в 'const TCHAR *'

Я работаю над кросс-платформенным проектом в C++, и у меня есть переменная с типом std::string и нужно преобразовать его в const TCHAR * - как правильно, могут быть функции из какой-то библиотеки?

UPD 1: - как я вижу в определении функции есть разделенные окна и реализации не-Windows:

#if defined _MSC_VER || defined __MINGW32__
#define _tinydir_char_t TCHAR
#else
#define _tinydir_char_t char
#endif

- так ли это на самом деле нет способа реализации без разделения для параметра отправки из std::string?

4 ответа

Решение

TCHAR Тип Windows и это определяется следующим образом:

#ifdef  UNICODE                     
typedef wchar_t TCHAR, *PTCHAR;
#else
typedef char TCHAR, *PTCHAR;
#endif

UNICODE макрос обычно определяется в настройках проекта (в случае, если вы используете проект Visual Studio в Windows).

Вы можете получить const TCHAR* от std::string (в большинстве случаев это ASCII или UTF8) следующим образом:

std::string s("hello world");
const TCHAR* pstring = nullptr;
#ifdef UNICODE
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wstr = converter.from_bytes(s);
    pstring = wstr.data();
#else
    pstring = s.data();
#endif

pstring будет результатом.

Но настоятельно не рекомендуется использовать TCHAR на других платформах. Лучше использовать строки UTF8 (char*) внутри std::string

Правильный способ кроссплатформенного преобразования из std::string в 'const TCHAR *'

TCHAR вообще не должен использоваться в кроссплатформенных программах; За исключением, конечно, при взаимодействии с вызовами Windows API, но они должны быть абстрагированы от остальной части программы, иначе это не будет кросс-платформенным. Таким образом, вам нужно только конвертировать между TCHAR струны и char строки в конкретном коде Windows.

Остальная часть программы должна использовать charи предпочтительно предположить, что он содержит строки в кодировке UTF-8. Если пользовательский ввод или системные вызовы возвращают строки, которые находятся в другой кодировке, вам необходимо выяснить, что это за кодировка, и соответствующим образом преобразовать.

Функциональность преобразования кодировки символов стандартной библиотеки C++ довольно слабая, поэтому она не очень полезна. Вы можете реализовать преобразование в соответствии со спецификацией кодирования или использовать стороннюю реализацию, как всегда.

может быть функции из какой-то библиотеки?

Я рекомендую это.

как я вижу в определении функции есть разделенные окна и реализации не-Windows

Используемая вами библиотека не предоставляет единого API для разных платформ, поэтому ее нельзя использовать по-настоящему кроссплатформенным способом. Вы можете написать библиотеку-оболочку с единообразными объявлениями функций, которая обрабатывает преобразование кодировки символов на платформах, которые в этом нуждаются.

Или вы можете использовать другую библиотеку, которая предоставляет единый API и прозрачно конвертирует кодировку.

Как уже отмечали другие, вы не должны использовать TCHAR, кроме как в коде, который взаимодействует с Windows API (или библиотеками, смоделированными после Windows API).

Другой альтернативой является использование классов / макросов преобразования символов, определенных в atlconv.h. CA2T преобразует 8-битную символьную строку в строку TCHAR. CA2CT преобразует в постоянную строку TCHAR (LPCTSTR). Предполагая, что ваши 8-битные строки имеют формат UTF-8, вы должны указать CP_UTF8 в качестве кодовой страницы для преобразования.

Если вы хотите объявить переменную, содержащую копию TCHAR std::string:

CA2T tstr(stdstr.c_str(), CP_UTF8);

Если вы хотите вызвать функцию, которая принимает LPCTSTR:

FunctionThatTakesString(CA2CT(stdsr.c_str(), CP_UTF8));

Если вы хотите создать std:: string из строки TCHAR:

std::string mystdstring(CT2CA(tstr, CP_UTF8));

Если вы хотите вызвать функцию, которая принимает LPTSTR, то, возможно, вам не следует использовать эти классы преобразования. (Но вы можете, если знаете, что вызываемая вами функция не изменяет строку за пределами ее текущей длины.)

Я столкнулся с boost.nowide на днях. Я думаю, что это будет делать именно то, что вы хотите.

http://cppcms.com/files/nowide/html/

Другие вопросы по тегам