Visual C++: преобразование типа данных PCSTR в LPCWSTR

У меня есть следующий код C++, который получает информацию запроса заголовка из экземпляра HttpContext:

public:
REQUEST_NOTIFICATION_STATUS
    OnBeginRequest(
    IN IHttpContext * pHttpContext,
    IN IHttpEventProvider * pProvider
    )
    {

        UNREFERENCED_PARAMETER(pHttpContext);
        UNREFERENCED_PARAMETER(pProvider);

        PCSTR header = pHttpContext->GetRequest()->GetHeader("Accept", NULL);
        WriteEventViewerLog(header);

Как видите, звонок:

pHttpContext->GetRequest()->GetHeader("Accept", NULL)** 

Возвращает тип данных PCSTR.

Но мне нужно передать WriteEventViewerLog с заголовком как "LPCWSTR", поскольку одна из функций, которые я использую внутри методов, принимает только строку в этом формате.

Из https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx об этих определениях строк:

Указатель на постоянную строку с нулевым символом в конце, состоящую из 8-битных символов Windows (ANSI). Для получения дополнительной информации см. Наборы символов, используемые шрифтами.

Этот тип объявлен в WinNT.h следующим образом:

typedef CONST CHAR * PCSTR;

И LPCWSTR:

Указатель на постоянную строку с нулевым символом в конце, состоящую из 16-битных символов Юникода. Для получения дополнительной информации см. Наборы символов, используемые шрифтами.

Этот тип объявлен в WinNT.h следующим образом:

typedef CONST WCHAR * LPCWSTR;

Я не нашел способ преобразования из этих двух типов данных. Я попытался привести заголовок к char*, а затем с помощью функции ниже перейти от char* к LPCWSTR:

LPWSTR charArrayToLPWSTR(char *source)
    {
        // Get required buffer size in 'wide characters'
        int nSize = MultiByteToWideChar(CP_ACP, 0, source, -1, NULL, 0);

        LPWSTR outString = new WCHAR[nSize];

        // Make conversion
        MultiByteToWideChar(CP_ACP, 0, source, -1, outString, nSize);
        return outString;
    }

Но это вернуло мне неверную строку (у меня нет полного ввода, но значение заголовка Accept было обрезано до "x;ih").

1 ответ

Решение
pHttpContext->GetRequest()->GetHeader("Accept", NULL);   

возвращает PCSTR тип данных.

Но мне нужно кормить WriteEventViewerLog с заголовком в виде LPCWSTR, поскольку одна из функций, которые я использую внутри методов, принимает только строку в этом формате.

Во-первых, давайте проясним значение этих "неясных" строк Windows API typedef s:

PCSTR:   const char *    
LPCWSTR: const wchar_t *

Итак, оба являются указателями на строки в стиле C, доступные только для чтения и заканчивающиеся NUL.

Разница в том, что PCSTR указывает на char строка на основе; LPCWSTR указывает на wchar_t на основе строки.

char Строки на основе могут иметь несколько "форм" (или кодировок), например, простые ASCII или Unicode UTF-8, или другие "многобайтовые" кодировки.

В случае вашей строки заголовка, я предполагаю, что это может быть простой ASCII или UTF-8 (обратите внимание, что ASCII является правильным подмножеством UTF-8).

wchar_t строки в Visual C++ - это строки Unicode UTF-16 (и это "родная" кодировка Unicode, используемая большинством Win32 API).

Итак, что вам нужно сделать, это преобразовать из char на основе строки к wchar_t на основе Предполагая, что ваш char строка на основе представляет строку Unicode UTF-8 (из которых чистый ASCII является подходящим подмножеством), вы можете использовать MultiByteToWideChar() Win32 API для преобразования.

Или вы можете использовать некоторые вспомогательные классы для упрощения задачи преобразования, например, помощники преобразования ATL. В частности, CA2W помощник с CP_UTF8 Флаг преобразования может пригодиться в вашем случае:

#include <atlconv.h>  // for CA2W
...

// Get the header string in Unicode UTF-8
PCSTR header = pHttpContext->GetRequest()->GetHeader("Accept", nullptr);

// Convert the header string from UTF-8 to Unicode UTF-16
WriteEventViewerLog( CA2W(header, CP_UTF8) );
Другие вопросы по тегам