Глобальное состояние в CRT
Некоторые функции в универсальной среде выполнения C (UCRT) используют глобальное состояние. Например, setlocale()
задает языковой стандарт для всей программы, который влияет на разделители цифр, текстовое кодовую страницу и т. д.
Глобальное состояние UCRT не является общим для приложений и ОС. Например, если приложение вызывает setlocale()
, оно не влияет на языковой стандарт для всех компонентов ОС, использующих время выполнения C, или наоборот.
Версии функций CRT для конкретной ОС
В UCRT функции, взаимодействующие с глобальным состоянием, имеют функцию "двойника" с _o_
префиксом. Например:
setlocale()
влияет на глобальное состояние, относящееся к приложению._o_setlocale()
влияет на глобальное состояние, совместно используемое всеми компонентами ОС, но не с приложениями.
Единственное различие между этими функциями "двойника" заключается в том, что при чтении и записи глобального состояния CRT версии, зависящие от ОС (то есть версии, начинающиеся с _o_
), используют копию ОС глобального состояния вместо копии глобального состояния приложения.
Версии этих функций, специфичные для ОС, находятся в ucrt.osmode.lib
. Например, версия setlocale()
для конкретной ОС — _o_setlocale()
Существует два способа изолировать состояние CRT компонента из состояния CRT приложения:
- Статическая компоновка компонента с помощью параметров
/MT
компилятора (Release) или/MTd
(Отладка). Дополнительные сведения см. в разделе /MD,/MT,/LD. Статическая компоновка может значительно увеличить двоичный размер. - начиная с версии Windows, начиная с версии Windows 10 2004, динамически связываться с CRT, но вызывать экспорты в режиме операционной системы (функции, начинающиеся с o). Для вызова экспортов в режиме операционной системы статическим образом, как и прежде, но игнорировать статический UCRT с помощью параметра
/NODEFAULTLIB:libucrt.lib
компоновщика (Release) или/NODEFAULTLIB:libucrtd.lib
(Debug). И добавьтеucrt.osmode.lib
к входным данным компоновщика. Дополнительные сведения см. в разделе параметр /NODEFAULTLIB (Ignore Library) .
Примечание
В исходном коде напишите setlocale()
, а не _o_setlocale()
. При связывании с ucrt.osmode.lib
Компоновщик автоматически подставляет версию функции, зависящую от ОС. То есть setlocale()
будет заменено на _o_setlocale()
.
Связывание используется для ucrt.osmode.lib
отключения некоторых вызовов UCRT, доступных только в режиме приложения. Попытка вызова этих данных приведет к ошибке компоновки.
Глобальное состояние, затронутое разделением приложения или ОС
Глобальное состояние, затронутое разделением состояния приложения и ОС, включает:
- Данные языкового стандарта
- Обработчики сигналов, заданные сигналом
- Подпрограммы завершения заданы методом Terminate
- пере_doserrno
- Состояние генерации случайных чисел, используемое СЛЧИС и srand
- Функции, возвращающие буфер, который пользователю не нужно выпустить: strtok, wcstok, _mbstoktmpnam, _wtmpnamasctime, _wasctimegmtime, _gmtime32, _gmtime64_fcvt_ecvtstrerror, _strerror, _wcserror, __wcserror
- Буфер , используемый _putch _putwch
- _set_invalid_parameter_handler, _set_thread_local_invalid_parameter_handler
- _set_new_handler и _set_new_mode
- фмоде
- Сведения о часовом поясе