通用 C 執行時間 (UCRT) 中的某些函式會使用全域狀態。 例如, setlocale() 設定整個程式的地區設定,這會影響數位分隔符、文字代碼頁等等。
UCRT 的全域狀態不會在應用程式和 OS 之間共用。 例如,如果您的應用程式呼叫 setlocale(),則不會影響任何使用 C 執行時間的作業系統元件的地區設定,或以其他方式運作。
CRT 函式的 OS 特定版本
在UCRT中,與全域狀態互動的函式前面加上 「twin」 函式 _o_。 例如:
-
setlocale()會影響應用程式特定的全域狀態。 -
_o_setlocale()會影響所有OS元件共用的全域狀態,但不會影響應用程式。
這些「對應項」函式的唯一差異在於,當他們讀取/寫入全域 CRT 狀態時,操作系統特定版本(也就是開頭 _o_的版本)會使用全域狀態的 OS 複本,而不是應用程式的全域狀態複本。
這些函式的OS特定版本位於 ucrt.osmode.lib中。 例如,OS 特定版本的 setlocale() 是 _o_setlocale()
有兩種方式可將元件的CRT狀態與應用程式的CRT狀態隔離:
- 使用編譯程式選項
/MT(release) 或/MTd[偵錯] 以靜態方式連結您的元件。 如需詳細資訊,請參閱 /MD、/MT、/LD。 靜態連結可以大幅增加二進位大小。 - 從 Windows 10 版本 2004 開始,動態連結至 CRT,但呼叫 OS 模式導出(開頭 為 o 的函式)。 若要呼叫 OS 模式匯出,請像之前一樣以靜態方式連結,但使用連結器選項
/NODEFAULTLIB:libucrt.lib(release) 或/NODEFAULTLIB:libucrtd.lib[偵錯] 忽略靜態 UCRT。 並將 新增ucrt.osmode.lib至連結器輸入。 如需詳細資訊,/NODEFAULTLIB(忽略連結庫)。
注意
在原始碼中,寫入 setlocale(),而不是 _o_setlocale()。 當您針對 ucrt.osmode.lib連結時,鏈接器會自動取代作業系統特定的函式版本。 也就是說, setlocale() 將會取代為 _o_setlocale()。
ucrt.osmode.lib針對的連結會停用某些僅適用於應用程式模式的 UCRT 呼叫。 嘗試呼叫這些函式會導致連結錯誤。
受應用程式/OS 隔離影響的全域狀態
受應用程式和 OS 狀態區隔影響的全域狀態包括:
- 地區設定數據
- 由設定的訊號處理程式
signal - 所設定的終止例程
terminate -
errno和_doserrno - 和所使用的
rand隨機數位產生狀態srand - 傳回使用者不需要釋放之緩衝區的函式:
strtok、、wcstok_mbstok
Tmpnam、_wtmpnam
asctime、_wasctime
gmtime、 、_gmtime32_gmtime64
_fcvt
_ecvt
strerror、 、_strerror、_wcserror__wcserror - 所使用的
_putch緩衝區,_putwch -
_set_invalid_parameter_handler、_set_thread_local_invalid_parameter_handler -
_set_new_handler和_set_new_mode fmode- 時區資訊