CRT 中的全域狀態
通用 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
- 時區資訊