CRT 中的全局状态

通用 C 运行时 (UCRT) 中的某些函数使用全局状态。 例如,setlocale() 可设置整个程序的区域设置,这会影响数字分隔符、文本代码页等。

UCRT 的全局状态不会在应用程序和 OS 之间共享。 例如,如果应用程序调用 setlocale(),这不会影响使用 C 运行时的所有 OS 组件的区域设置,反之亦然。

特定于 OS 的 CRT 函数版本

在 UCRT 中,与全局状态交互的函数具有前缀为 _o_ 的“孪生”函数。 例如:

  • setlocale() 影响特定于应用的全局状态。
  • _o_setlocale() 影响所有 OS 组件共享的全局状态,但不影响应用共享的全局状态。

这些“孪生”函数的唯一区别是,当它们读取/写入全局 CRT 状态时,特定于 OS 的版本(即以 _o_ 开头的版本)使用 OS 的全局状态副本,而不使用应用的全局状态副本。

这些特定于 OS 的函数版本位于 ucrt.osmode.lib 中。 例如,特定于 OS 的 setlocale() 版本为 _o_setlocale()

可通过两种方法将组件的 CRT 状态与应用的 CRT 状态隔离:

  • 使用编译器选项 /MT(发布)或 /MTd(调试)静态链接组件。 有关详细信息,请参阅 /MD、/MT、/LD。 静态链接会大大增加二进制文件的大小。
  • 从 Windows 10 版本 2004 开始的 Windows 版本中,动态链接到 CRT,但调用 OS 模式的导出项(以 o 开头的函数)。 若要调用 OS 模式的导出项,请像以前一样进行静态链接,但使用链接器选项 /NODEFAULTLIB:libucrt.lib(发布)或 /NODEFAULTLIB:libucrtd.lib(调试)忽略静态 UCRT。 然后将 ucrt.osmode.lib 添加到链接器输入。 有关详细信息,请参阅 /NODEFAULTLIB(忽略库)

注意

在源代码中,写入 setlocale(),而不是 _o_setlocale()。 链接 ucrt.osmode.lib 时,链接器将自动替换特定于 OS 的函数版本。 即,setlocale() 将被替换为 _o_setlocale()

链接 ucrt.osmode.lib 将禁用某些仅在应用模式下可用的 UCRT 调用。 尝试调用这些函数将导致链接错误。

受应用/OS 隔离影响的全局状态

受应用和 OS 全局状态隔离影响的全局状态包括:

另请参阅

C 运行时库参考