2022

[Rust] Unit-Like Struct 在 Embedded Rust 中的應用

在處理嵌入式系統時常會需要控制 GPIO。所謂的 GPIO(General-Purpose I/O),就是 IC 的某些 pin 腳,可以透過軔體設定為「input(偵測外部的訊號是高電位還是低電位)」或是「output(對外輸出高電位或低電位)」狀態。

理論上來說,當 GPIO 設定為 input 狀態時,叫它「輸出高電位」是沒有意義的。反之,設定為 output 時,去讀取 pin 的電位狀態可能也是沒意義的。因此在設計存取 GPIO 的 API 時,最好能有適當的防呆機制。

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,用來表示字串的結尾。

將只有 ASCII 範圍的 wstring 轉換成 string

Windows 的程式,若是 Unicode enabled 的話,預設使用的編碼是 UTF-16,每個字元的型別為 wchar_t。這樣的字串,無法使用 std::string 處理,必須改用 std::wstring。但有時候,現有的函式如果只吃 std::string,而且我們的字串又只包含有 ASCII 定義的字元(也就是只有英文及半型符號)的話,我們就必須把 std::wstring 轉成 std::string

有一種比較偷懶的做法:

std::wstring ws(L"Hello");
std::string s(ws.begin(), ws.end());

但是在比較嚴謹的 C++ 編譯器(例如 VS 2022),就會發出警告(因為隱式把 wchar_t 轉換成 char,可能造成資料流失)。想要避開警告,就必須明確使用 static_cast<> 進行資料轉換。此時就可以利用 std::transform() 來做:

std::wstring ws(L"Hello");
std::string s(ws.size(), 0);
std::transform(ws.begin(), ws.end(), s.begin(), [](wchar_t c){
    return static_cast<char>c;
});

[Rust] 如何產生靜態連結的 Win32/64 執行檔?

在預設情況下,Windows 版本的 rustc 編譯出來的 Win32/Win64 執行檔,會需要一些 Visual C++ 的 DLL 才能執行。對於軟體開發人員來說,在建構開發環境的過程中,這些 DLL 都會被安裝到系統之中,因此不太會遇到編譯出來的執行檔無法執行的問題;但若是我們要將執行檔給別人、在沒有安裝開發環境的電腦上執行,往往就會遇到問題。

我們可以利用 Visual Studio 所內建的工具程式 dumpbin(加上參數 /dependents)來檢查執行檔的 DLL 依存關係:

上面列出來的 DLL 中,KERNEL32.DLLbcrypt.dll 是 Windows 內建的 DLL,其他的都是 Visual C++ 提供的 DLL,不見得每一台 PC 上都會有這些 DLL。

如果希望 rustc 採用靜態連結的方式、移除對 VC++ DLL 的依存性,可以在 Rust 專案中的 .cargo\config 檔案中,加上這兩行:

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

然後重新編譯程式。這樣就可以了:

  • 資料來源:https://stackoverflow.com/questions/31770604/how-to-generate-statically-linked-executables