【问题标题】:Thread specific locale manipulation in C++C++ 中的线程特定语言环境操作
【发布时间】:2011-07-03 07:47:35
【问题描述】:

是否有任何标准方法在每个线程跨平台进行区域设置?我看到 xlocale 提供了 uselocale,但它在 Windows 中不受支持。有“_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);”在 Windows 中,之后 setlocale 在每个线程的基础上工作。我的问题是,是否有一个库以独立于平台的方式提供这些特定于语言环境的操作???还是其他方式?

谢谢, 悟空。

【问题讨论】:

  • 你想做什么? C++ 提供每个流 语言环境,这还不够吗?
  • 标准库有 <locale> 标头,它允许您实例化每个线程的语言环境对象。不确定这些是否满足您的需求。
  • @Bo Persson:: 这需要重写编写的代码。我只需要为每个线程设置语言环境设置。它已经在 Windows 和 Unix 中可用。因此,如果有一种可移植的方式(使用一些库),我正在寻找它。

标签: c++ thread-safety locale


【解决方案1】:

我也遇到过同样的问题,我最终为它写了一些小的交叉兼容性代码。我试图尽可能接近specification,但它确实有一些限制。

在此代码中,newlocale 不允许您指定基本语言环境,并且您也无法混合类别掩码。但是对于不同语言环境之间的一些基本切换,这应该足够了。

// Locale Cross-Compatibility
#ifdef _WIN32
#define locale_t         _locale_t
#define freelocale       _free_locale

#define LC_GLOBAL_LOCALE ((locale_t)-1)
#define LC_ALL_MASK      LC_ALL
#define LC_COLLATE_MASK  LC_COLLATE
#define LC_CTYPE_MASK    LC_CTYPE
#define LC_MONETARY_MASK LC_MONETARY
#define LC_NUMERIC_MASK  LC_NUMERIC
#define LC_TIME_MASK     LC_TIME

// Base locale is ignored and mixing of masks is not supported
#define newlocale(mask, locale, base) _create_locale(mask, locale)

locale_t uselocale(locale_t new_locale)
{
    // Retrieve the current per thread locale setting
    bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);

    // Retrieve the current thread-specific locale
    locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;

    if(new_locale == LC_GLOBAL_LOCALE)
    {
        // Restore the global locale
        _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
    }
    else if(new_locale != NULL)
    {
        // Configure the thread to set the locale only for this thread
        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);

        // Set all locale categories
        for(int i = LC_MIN; i <= LC_MAX; i++)
            setlocale(i, new_locale->locinfo->lc_category[i].locale);
    }

    return old_locale;
}
#endif

将该代码放入您的项目中,您就可以在任何平台上切换每个线程的语言环境,如下所示:

#include <locale.h>
#ifdef __APPLE__
#include <xlocale.h>
#endif

// Apply a new locale to this thread
locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
locale_t old_locale = uselocale(locale);

// Print out some text
printf("Always use dot-decimal notation: %f", 1.5);

// Restore the global locale
uselocale(old_locale);
freelocale(locale);

【讨论】:

    【解决方案2】:

    Boost::Locale 提供基于the iconv library 的跨平台语言环境界面。如果您希望 C 标准库函数在设置语言环境后立即正常运行,那么它可能不是您理想的界面。相反,您将手动将语言环境作为对象进行管理,并明确使用它们。您 explicitly generate locales 并使用它们 to create comparators 以及您需要的其他任何特定于语言环境的东西。

    一方面,这意味着您之前编写的任何依赖于特定语言环境的开发代码都必须重写。另一方面,隐藏在引擎盖下的陷阱要少得多,因为您要明确处理在哪里使用什么语言/编码。

    【讨论】:

    • 这似乎是一个正在开发的库。所以这对我们来说是不可行的。
    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多