Глобальное состояние в CRT
Некоторые функции в универсальной среде выполнения C (UCRT) используют глобальное состояние. Например, setlocale()
задает языковой стандарт для всей программы, который влияет на разделители цифр, текстовую кодовую страницу и т. д.
Глобальное состояние UCRT не совместно используется между приложениями и ОПЕРАЦИОННОй системой. Например, если приложение вызывает setlocale()
, он не повлияет на языковой стандарт для компонентов ОС, использующих время выполнения C, или наоборот.
Версии функций CRT для конкретных ОС
В UCRT функции, взаимодействующие с глобальным состоянием, имеют функцию "двойника" с префиксом _o_
. Например:
setlocale()
влияет на глобальное состояние приложения._o_setlocale()
влияет на глобальное состояние, совместно используемое всеми компонентами ОС, но не приложениями.
Единственное различие между этими функциями двойников заключается в том, что при чтении и записи глобального состояния CRT версии для конкретной ОС (то есть версии, начинающиеся с _o_
) используют копию глобального состояния ОС вместо копии глобального состояния приложения.
Версии этих функций зависят от ucrt.osmode.lib
операционной системы. Например, версия операционной системы зависит от конкретной setlocale()
ос _o_setlocale()
Существует два способа изолировать состояние CRT компонента от состояния CRT приложения:
- Статически свяжите компонент с помощью параметров
/MT
компилятора (выпуск) или/MTd
(отладка). Дополнительные сведения см. в разделе /MD, /MT, /LD. Статическое связывание может значительно увеличить двоичный размер. - Начиная с версий Windows, начиная с Windows 10 версии 2004, динамически связываются с CRT, но вызывают экспорты в режиме ОС (функции, начинающиеся с o). Чтобы вызвать экспорт в режиме ОС, статически свяжите как и раньше, но игнорируйте статический UCRT с помощью параметра
/NODEFAULTLIB:libucrt.lib
компоновщика (выпуска) или/NODEFAULTLIB:libucrtd.lib
(отладки). И добавьтеucrt.osmode.lib
в входные данные компоновщика. Дополнительные сведения см. в разделе/NODEFAULTLIB
(игнорировать библиотеки ).
Примечание
В исходном коде напишите setlocale()
, а не _o_setlocale()
. При связывании со ucrt.osmode.lib
ссылкой компоновщик автоматически подставляет версию функции для конкретной ОС. То есть setlocale()
будет заменено _o_setlocale()
на .
Связывание отключает ucrt.osmode.lib
некоторые вызовы UCRT, доступные только в режиме приложения. Попытка вызова этих функций приведет к ошибке ссылки.
Глобальное состояние, затронутое разделением приложений и ОС
Глобальное состояние, затронутое разделением состояния приложения и ОС, включает:
- Данные языкового стандарта
- Обработчики сигналов, заданные по
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
- Сведения часового пояса