C++ C++;boost在使用区域设置时崩溃
我试图使用boost库为我的string类提供i18支持。 我正在使用Microsoft Visual studio编译器VC10和64位Windows 7计算机 我能够编译我的应用程序并将其链接到boost库,但是我的应用程序在调用boost::locale::to_upper()时崩溃 以下是我编写的代码C++ C++;boost在使用区域设置时崩溃,c++,boost,crash,locale,C++,Boost,Crash,Locale,我试图使用boost库为我的string类提供i18支持。 我正在使用Microsoft Visual studio编译器VC10和64位Windows 7计算机 我能够编译我的应用程序并将其链接到boost库,但是我的应用程序在调用boost::locale::to_upper()时崩溃 以下是我编写的代码 #include <boost/locale.hpp> #include <boost/algorithm/string/case_conv.hpp> #inclu
#include <boost/locale.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/system/config.hpp>
String::MakeUpper()()
{
boost::locale::generator gen;
std::locale loc = gen("");
std::locale::global(loc);
std::string str2 = boost::locale::to_upper("001Öä", loc); // application crashes here.
std::string str3 = boost::locale::to_upper("001Öä"); // This also does not work
}
#包括
#包括
#包括
字符串::MakeUpper()()
{
boost::locale::gen生成器;
std::LOCE loc=gen(“”);
std::locale::global(loc);
std::string str2=boost::locale::to_upper(“001Öä”,loc);//应用程序在此崩溃。
std::string str3=boost::locale::to_upper(“001ä”);//这也不起作用
}
崩溃发生在以下函数中。此函数引发错误强制转换异常
template<class _Facet> inline
const _Facet& __CRTDECL use_facet(const locale& _Loc)
{ // get facet reference from locale
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
const locale::facet *_Psave =
_Facetptr<_Facet>::_Psave; // static pointer to lazy facet
size_t _Id = _Facet::id;
const locale::facet *_Pf = _Loc._Getfacet(_Id);
if (_Pf != 0)
; // got facet from locale
else if (_Psave != 0)
_Pf = _Psave; // lazy facet already allocated
else if (_Facet::_Getcat(&_Psave, &_Loc) == (size_t)(-1))
#if _HAS_EXCEPTIONS
_THROW_NCEE(bad_cast, _EMPTY_ARGUMENT); // lazy disallowed
....
....
....
}
模板内联
常量方面和CRTDECL使用方面(常量区域设置和位置)
{//从区域设置获取方面引用
_BEGIN\u LOCK(\u LOCK\u LOCALE)//线程锁,使get原子
const locale::facet*\u Psave=
_Faceptr::\u Psave;//指向惰性方面的静态指针
size\u t\u Id=\u Facet::Id;
const locale::facet*\u Pf=\u Loc.\u Getfacet(\u Id);
如果(_Pf!=0)
;//从区域设置中获取方面
否则如果(_Psave!=0)
_Pf=\u Psave;//已分配惰性方面
如果(_Facet::_Getcat(&_Psave,&_Loc)==(size_t)(-1))
#如果有例外情况
_抛出(错误的抛出,空的参数);//不允许懒惰
....
....
....
}
你能帮帮我吗
问候,,
Sumit我在Windows7 64位上的VisualStudio2008应用程序中使用Boost 1.55的静态库构建时遇到了同样的问题,其中主可执行文件和两个DLL都链接到Boost。我不确定你的问题是否与我的问题相同,因为你没有提到使用DLL,但当我第一次开始调查这个问题时,我认为这与我无关 如果您只是对解决此问题的最直接的方法感兴趣,那么将Boost构建为共享库就可以了。具体来说,我的意思是将b2命令行的
链接
属性设置为共享
,而不是静态
解释
使用静态库生成出现问题的原因是Boost.Locale使用对象来执行文本转换操作,如大写和规格化std::locale::facet
类需要有一个id
静态成员变量,该变量在静态初始化期间构造时,其唯一值由标准库实现分配
使用静态库时的问题是,所有可执行文件和DLL都从静态库中获取自己的静态成员变量的不同副本,如中所述。使用boost::locale::generator::operator()
生成区域设置时,它只会将std::locale::facet
对象安装到具有id
成员变量的区域设置中,该变量是包含该调用的同一DLL或可执行文件的一部分
正如我上面所说的,解决这个问题最直接的方法是将Boost构建为一个共享库。这样,Boost.Locale的静态成员变量将只有一个副本。具体来说,它们将位于Boost.Locale DLL中
替代解决方案
通过使用Boost.locale确保所有DLL和可执行文件中的所有std::locale::facet
对象都安装到您尝试使用的std::locale
对象中,可以使用Boost的静态库构建实现这一点
您可以使用下面的一些代码来实现这一点。对于DLL,当其第二个参数fdreason
为DLL\u PROCESS\u ATTACH
时,您可以在DllMain
中调用它,对于可执行文件,您可以在WinMain
或其他一些应用程序入口点(如果您使用的是MFC或Qt)中调用它
代码的重要部分是,它在每次运行时都使用全局区域设置作为基本区域设置,并将新生成的区域设置安装为新的全局区域设置。这与boost::locale::generator::operator()
所做的不同,因为它使用std::locale::classic
作为基本区域设置,并且不能修改。通过从每个DLL和可执行文件调用它,您将把它们的每个std::locale::facet
对象安装到全局语言环境中
void setup_global_locale()
{
const boost::locale::generator generator;
const std::locale locale = generator.generate( std::locale(), "" );
std::locale::global( locale );
}