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) );