Globaler Status in der CRT
Einige Funktionen in der universellen C-Runtime (UCRT) verwenden den globalen Zustand. Legt beispielsweise setlocale()
das Gebietsschema für das gesamte Programm fest, das sich auf die Zifferntrennzeichen, die Textcodeseite usw. auswirkt.
Der globale Zustand der UCRT wird nicht zwischen Anwendungen und dem Betriebssystem gemeinsam genutzt. Wenn Ihre Anwendung beispielsweise aufruft setlocale()
, wirkt es sich nicht auf das Gebietsschema für alle Betriebssystemkomponenten aus, die die C-Laufzeit verwenden, oder umgekehrt.
Betriebssystemspezifische Versionen von CRT-Funktionen
In der UCRT verfügen Funktionen, die mit dem globalen Zustand interagieren, über eine "Twin"-Funktion, die dem Präfix entspricht _o_
. Beispiel:
setlocale()
wirkt sich auf den globalen Zustand aus, der für die App spezifisch ist._o_setlocale()
wirkt sich auf den globalen Zustand aus, der von allen Betriebssystemkomponenten, aber nicht von Apps gemeinsam genutzt wird.
Der einzige Unterschied zwischen diesen "Twin"-Funktionen besteht darin, dass beim Lesen/Schreiben des globalen CRT-Zustands die betriebssystemspezifischen Versionen (d. h. die Versionen, die mit _o_
) die Betriebssystemkopie des globalen Zustands anstelle der Kopie des globalen Zustands der App verwenden.
Die betriebssystemspezifischen Versionen dieser Funktionen sind in ucrt.osmode.lib
. Die betriebssystemspezifische Version von setlocale()
z. B. lautet _o_setlocale()
Es gibt zwei Möglichkeiten, den CRT-Zustand Ihrer Komponente aus dem CRT-Zustand einer App zu isolieren:
- Verknüpfen Sie Die Komponente mithilfe von Compileroptionen
/MT
(Release) oder/MTd
(Debug) statisch. Ausführliche Informationen finden Sie unter /MD, /MT, /LD. Statische Verknüpfungen können die Binäre Größe erheblich erhöhen. - Ab Windows-Versionen ab Windows 10, Version 2004, verknüpfen Sie dynamisch mit dem CRT, rufen jedoch die Betriebssystemmodusexporte auf (die Funktionen, die mit o beginnen). Um die Exporte des Betriebssystemmodus aufzurufen, verknüpfen Sie die statische UCRT jedoch wie zuvor, ignorieren Sie jedoch die statische UCRT mithilfe der Linkeroption
/NODEFAULTLIB:libucrt.lib
(Release) oder/NODEFAULTLIB:libucrtd.lib
(Debug). Und fügen Sie der Linkereingabe hinzuucrt.osmode.lib
. Weitere Informationen finden Sie unter/NODEFAULTLIB
(Bibliotheken ignorieren).
Hinweis
Schreiben Sie setlocale()
im Quellcode , nicht _o_setlocale()
. Wenn Sie eine Verknüpfung herstellen ucrt.osmode.lib
, ersetzt der Linker automatisch die betriebssystemspezifische Version der Funktion. Das heißt, setlocale()
wird durch _o_setlocale()
ersetzt werden.
Beim Verknüpfen werden ucrt.osmode.lib
einige UCRT-Aufrufe deaktiviert, die nur im App-Modus verfügbar sind. Der Versuch, diese Funktionen aufzurufen, führt zu einem Linkfehler.
Globaler Zustand, der von der Trennung von Apps/Betriebssystemen betroffen ist
Der globale Zustand, der von der Trennung des App- und Betriebssystemzustands betroffen ist, umfasst:
- Gebietsschemadaten
- Für Signalhandler festgelegt nach
signal
- Beendigungsroutinen, die von
terminate
errno
und_doserrno
- Generierungszustand der Zufallszahl, der von
rand
undsrand
- Funktionen, die einen Puffer zurückgeben, den der Benutzer nicht freigeben muss:
strtok
, ,wcstok
_mbstok
Tmpnam
,_wtmpnam
asctime
,_wasctime
gmtime
,_gmtime32
,_gmtime64
_fcvt
_ecvt
strerror
,_strerror
,_wcserror
,__wcserror
- Der von
_putch
,_putwch
_set_invalid_parameter_handler
,_set_thread_local_invalid_parameter_handler
_set_new_handler
und_set_new_mode
fmode
- Zeitzoneninformationen