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

 

posted @ 2015-02-22 14:55  wu_overflow  阅读(576)  评论(0编辑  收藏  举报