关于字符串:Visual C ++:将数据类型PCSTR转换为LPCWSTR

Visual C++: Convert data type PCSTR to LPCWSTR

我有以下C ++代码,可从HttpContext实例检索标头请求信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
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);

如您所见,该调用:

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

返回PCSTR数据类型。

但是我需要将带有标头的WriteEventViewerLog作为" LPCWSTR"来提供,因为我在方法内部使用的功能之一仅接受该格式的字符串。

从https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa383751%28v=vs.85%29.aspx,了解以下字符串定义:

A pointer to a constant null-terminated string of 8-bit Windows
(ANSI) characters. For more information, see Character Sets Used By
Fonts.

This type is declared in WinNT.h as follows:

typedef CONST CHAR *PCSTR;

和LPCWSTR:

A pointer to a constant null-terminated string of 16-bit Unicode
characters. For more information, see Character Sets Used By Fonts.

This type is declared in WinNT.h as follows:

typedef CONST WCHAR *LPCWSTR;

我没有找到从这两种数据类型转换的方法。 我尝试将标头转换为char *,然后使用下面的函数从char *转换为LPCWSTR:

1
2
3
4
5
6
7
8
9
10
11
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);

returns a PCSTR data type.

But I need to feed the WriteEventViewerLog with header as a
LPCWSTR, since one of the functions that I use inside the methods
only accepts the string in that format.

首先,让我们澄清一下这些"晦涩"的Windows API字符串typedef的含义:

1
2
PCSTR:   const char *    
LPCWSTR: const wchar_t *

因此,它们都是指向NUL终止的只读C样式字符串的指针。

不同之处在于PCSTR指向基于char的字符串; LPCWSTR指向基于wchar_t的字符串。

基于char的字符串可以具有几种"形式"(或编码),例如简单ASCII或Unicode UTF-8或其他"多字节"编码。

对于您的标头字符串,我假设它可以是简单的ASCII或UTF-8(请注意ASCII是UTF-8的适当子集)。

Visual C ++中基于wchar_t的字符串是Unicode UTF-16字符串(这是大多数Win32 API使用的"本机" Unicode编码)。

因此,您要做的就是将基于char的字符串转换为基于wchar_t的字符串。假设基于char的字符串表示Unicode UTF-8字符串(纯ASCII是其适当的子集),则可以使用MultiByteToWideChar() Win32 API进行转换。

或者,您可以使用一些帮助程序类来简化转换任务,例如ATL转换帮助程序。特别是,带有CP_UTF8转换标志的CA2W助手可以在您的情况下派上用场:

1
2
3
4
5
6
7
8
#include   // 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) );