Windows Programming

追求寬字元字串和一般字元字串的轉換效率

在 Windows 之中,想將標準字元 (char) 字串轉換成寬字元 (wchar_t) 字串,通常會使用 MultiByteToWideChar() 這個 Win32 API。這個 API 的 prototype 如下:

int MultiByteToWideChar(
    UINT CodePage,              // [in] 說明輸入字串的編碼。本文假設都為 UTF-8。
    DWORD dwFlags,              // [in] 選項旗標。本文不討論。
    LPCSTR lpMultiByteStr,      // [in] 指向輸入字串的指標。
    int cchMultiByte,           // [in] 指定要處理輸入字串 char 個數。-1 表示處理到結尾的空字元。
    LPWSTR lpWideCharStr,       // [out; optional] 輸出的 buffer。
    int cchWideChar             // [in] 描述 lpWideCharStr 的 buffer 大小,單位為 sizeof(wchar_t)。
);

比較有趣的設計是:如果 lpWideCharStr 傳入的值是 nullptr,而 cchWideChar 是 0 的話,這個 API 的回傳值就會是「該字串完成轉換後所需要的 buffer 大小」。這是因為在不同的編碼下每個「文字」的大小可能不一樣;混用各種文字的字串,經過編碼轉換後,所需要的長度並沒有一定的公式可循,必須得真的轉換過一次,才能得知所需的長度 。

由於考慮到記憶體配置與安全性的問題,一般人在使用這個 API 時,會呼叫兩次:第一次取得所需的 buffer 大小、配置適當的記憶體後,再呼叫第二次,把轉換結果填入 buffer。把整個流程寫成函式的話,會長成這個樣子:

Read More

[翻譯] Eric 的 BSTR 完全攻略

(原文出處:https://ericlippert.com/2003/09/12/erics-complete-guide-to-bstr-semantics/


如果你曾經用 C 或 C++ 寫過任何使用到 COM 物件的程式,你一定看過類似的程式碼:

STDMETHODIMP CFoo:Bar(BSTR bstrABC)
{ ... }

這個 BSTR 到底是三小?它和 WCHAR* 又有什麼區別?

像 C 或 C++ 這種低階語言,你有絕對的自由可以決定:究竟要用什麼方式實作某種概念。Unicode 字串就是個絕佳範例。用 C++ 來表示長度為 n 個字元的 Unicode 字串的標準方法是一個指向 2 * (n + 1) bytes 記憶體空間的指標。這塊空間中的前 2 * n bytes 是用來表示 UTF-16 編碼字元的無號短整數 (unsigned short integers),最後 2 個 bytes 的內容則是 0,用來表示字串的結尾。