2024

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

在 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

關於 Windows 中程式參數編碼的一些討論

標題實在下得很爛,但不知道怎麼下比較好。

這篇主要是回答 PTT 上 C_CPP 板,有 Windows programming 的初學者在問 C 程式的命令列為什麼不吃 Unicode 的問題。

這個問題其實是很大的。我的回答可能也不是很清楚。但好歹是我花時間寫的東西,就留在這邊記錄一下吧!


首先,我複議 lwecloud(註:另一位鄉民)的說法:都已經 2023 年,Windows 都是 NT-based 的了,不要再用 MBSC/ANSI 了。

你要做的事,不是把 compiler option 改成 MBSC,而是要想為什麼你在 Unicode 下編譯/執行有問題?

Read More

2024 亞洲門戶交流賽圖文雜記 (Day 3 & 4)

散策

昨天沒有開車去球場。回程是搭晚宴時才認識的新朋友的便車回來。
我們預約了今天要一起去吃美崎牛(我是一定會喝酒的),所以他邀我今早再坐他的車前往球場。
掙扎了一下,還是決定依自己的步調出門,慢慢走到球場。

經過昨天太陽的荼毒,今天不敢穿短袖出門了。
套了一件薄外套。寧可流點汗,也不要被曬傷啊!

住宅區一隅。總覺得那顆長在二樓高度的樹很有趣。配上斷垣殘壁,很有感覺。

Read More

2024 亞洲門戶交流賽圖文雜記 (Day 1)

出發

一大早六點就出門,出發去坐高鐵,然後換機捷到機場。
清晨的空氣特別冷冽,在機捷的月台上格外能感受到陣陣刺骨的冷風。
石垣島也是一樣的天氣嗎?

大約七點二時抵達機場報到櫃檯,結果發現場面比我想像的混亂不少....

主要應該是因為球員行李和球具太多,所以報到的進度有點緩慢。
我原本以為球員會有另外的通道、球具也會專案處理的說....看樣子是想太多了。

Read More

在 VS Code 中給 Rust 專案使用的 launch.json 範例

(更新:rust-analyzer 也有自動產生 launch.json 的功能。可以停留在 main.rs 上,按 F1,選取 "rust-analyzer: Generate launch configuration" 即可。)

留個筆記,不然每次都要靠 google....

{
    // 使用 IntelliSense 以得知可用的屬性。
    // 暫留以檢視現有屬性的描述。
    // 如需詳細資訊,請瀏覽: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type":"lldb",
            "request": "launch",
            "name": "Debug",
            "program": "${workspaceFolder}/target/debug/${workspaceFolderBasename}",
            "args": [],
            "cwd": "${workspaceRoot}",
            "sourceLanguages": [
                "rust"
            ]
        }
    ]
}

然後記得要按 VS Code 自已的 debug/run 按鈕去執行,不要按 main() 上方的 "Run/Debug" inlay。後者不會吃 launch.json 中的 args

參考來源:Setting up a generic launch.json for Rust in VSCode