Windows 上将一个由多字节字符串转换为 Unicode 形式
我们使用 Windows 函数 MultiByteToWideChar 将多字节字符串转换为宽字符串。如下所示:
int MultiByteToWideChar(
UINT uCodePage, //标识了与多字节字符关联的一个代码页值
DWORD dwFlags, //允许进行额外控制, 但一般传入 0
PCSTR pMultiByteStr, //要转换的字符串
int cbMultiByte, //字符串的长度, 若传入 -1, 则自动判断长度
PWSTR pWideCharStr, //得到的 Unicode 字符串会传入指定的内存缓冲区
int cchWideChar); //指定缓冲区的最大长度
转换的具体步骤:
1. 调用 MultiByteToWideChar,
为 pWideCharStr 参数传入 NULL,
为 cchWideChar 参数传入 0,
为 cbMultiByte 参数传入 -1。
2. 分配足以容纳转换后的 Unicode 字符串的一个内存块。
它的大小是上一个 MultiByteToWideChar 调用的返回值乘以 sizeof(wchar_t)。
3. 再次调用 MultiByteToWideChar,这一次
将缓冲区地址作为 pWideCharStr 参数的值传入,
将第一次 MultiByteToWideChar 调用的返回值乘以 sizeof(wchar_t) 后得到大小作为 cchWideChar 参数的值传入。
4. 使用转换后的字符串。
5. 释放Unicode字符串占用的内存块。
以下是一个例子, 一个反转字符串的简单函数的两个版本:
BOOL StringReverseW (PWSTR pWideCharStr, DWORD cchLength)
{
//Get a pointer to the last character in the string
PWSTR pEndOfStr = pWideCharStr +
wcsnlen_s (pWideCharStr, cchLength) - 1;
//Repeat until we reach the center character in the string
while (pWideCharStr < pEndOfStr) {
//Save a character in a temporary variable
auto cCharT = *pWideCharStr;
//Put the last character in the first character
*pWideCharStr = *pEndOfStr;
//Put the temporary variable int the last character
*pEndOfStr = cCharT;
++pWideCharStr;
--pEndOfStr;
}
return (TRUE);
}
BOOL StringReverseA (PSTR pMultiByteStr, DWORD cchLength)
{
// Caculate thr number of character needed to hold
// the wide-character of the string.
int32_t nLenOfWideCharStr = MultiByteToWideChar (
CP_ACP, 0, pMultiByteStr, cchLength, nullptr, 0);
// Allocate memory from the process's default heap to
// acconmmodate the size of the wide-character string
// Don't forget that MiltiByteToWideChar return the
// number of characters, not the number of bits, so
// you must multiply by the size of a wide character.
PWSTR pWideCharStr = static_cast<PWSTR>(
HeapAlloc(GetProcessHeap(), 0,
nLenOfWideCharStr * sizeof(wchar_t)));
BOOL fOk = FALSE;
if (pWideCharStr == nullptr) {
return fOk;
}
//Convert the nultibyte string to a wide-character string.
MultiByteToWideChar (CP_ACP, 0, pMultiByteStr, cchLength,
pWideCharStr, nLenOfWideCharStr);
// Call the wide-character version of this
// function to do actual work.
fOk = StringReverseW (pWideCharStr, cchLength);
if (fOk) {
// Conver the wide-character string back
// to a multibyte string.
WideCharToMultiByte (
CP_ACP, 0, pWideCharStr, cchLength,
pMultiByteStr, (int)strlen(pMultiByteStr),
nullptr, nullptr);
}
//Free the memory containing the wide-character string
HeapFree (GetProcessHeap (), 0, pWideCharStr);
return (fOk);
}