使用区域设置时C ++ Boost崩溃 [英] C++ boost crashes while using locale
问题描述
我正在尝试使用boost库为我的字符串类提供i18支持. 我正在使用Microsoft Visual Studio编译器VC10和64位Windows 7计算机.
我能够编译我的应用程序并将其与boost库链接,但是在调用boost :: locale :: to_upper()时我的应用程序崩溃了.
以下是我编写的代码.
#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
}
崩溃发生在以下函数中.此函数将引发错误的强制转换异常.
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
....
....
....
}
能请你帮我吗?
关于, 提交
在Windows 7 64位版本的Visual Studio 2008应用程序中使用Boost 1.55的静态库版本时,我遇到了相同的问题,其中主可执行文件和所有都链接到Boost的DLL.我不确定您的问题是否与我的相同,因为您没有提到使用DLL,但是当我第一次开始调查此问题时,我认为这并不重要.
如果您只对最简单的解决方法感兴趣,那么将Boost构建为共享库就可以了.具体来说,我的意思是将b2命令行的link
属性设置为shared
而不是static
.
说明
使用静态库构建的原因是由于使用 std::locale::facet
对象用于执行其文本转换操作,例如大写和规范化. std::locale::facet
类必须具有id
静态成员变量,该变量的唯一值是在静态初始化期间构造时由标准库实现分配的.
使用静态库时出现的问题是,所有可执行文件和DLL从静态库中获得其自己的静态成员变量的不同副本,如 该代码的重要部分是每次运行时都使用全局语言环境作为基本语言环境,并将新生成的语言环境安装为新的全局语言环境.这与 I am trying to use boost library for providing i18 support to my string class.
I am using Microsoft Visual studio compiler VC10 and 64 bit Windows 7 machine. I am able to compile and link my application with the boost library however my application crashes while invoking boost::locale::to_upper(). Following is the code I wrote. The crash happens in the following function. this function throws bad cast exception. Could you please help me out. Regards,
Sumit I had this same issue when using a static library build of Boost 1.55 in a Visual Studio 2008 application on Windows 7 64-bit where both the main executable and a couple DLLs all linked to Boost. I'm not sure if your issue is the same as mine since you didn't mention using DLLs, but that wasn't something I thought was relevant when I first started investigating this. If you're just interested in the most straight-forward way to fix this, then building Boost as a shared library should do it. Specifically, I mean setting the The reason using a static library build has a problem is due to Boost.Locale using The problem with this when using a static library is that all executables and DLLs get their own distinct copy of static member variables from a static library, as discussed in Shared global variable in C++ static library. When you use As I said above, the most straight-forward way to fix this is to build Boost as a shared library. That way there will only be one copy Boost.Locale's static member variables. Specifically, they'll be in the Boost.Locale DLL. You can do this with a static library build of Boost by making sure all of You can use some code like below to do this. For DLLs, you could call this in The important piece of the code is that it's using the global locale as the base locale each time it's run, and it installs the newly-generated locale as the new global locale. This is different from what 这篇关于使用区域设置时C ++ Boost崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!boost::locale::generator::operator()
的操作不同,因为它使用std::locale::classic
作为基本语言环境,并且无法修改.通过从每个DLL和可执行文件中调用它,可以将它们的每个std::locale::facet
对象安装到全局语言环境中.#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
}
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
....
....
....
}
link
property of the b2 command-line to shared
rather than static
.Explanation
std::locale::facet
objects for doing its text conversion operations like upper-casing and normalizing. std::locale::facet
classes are required to have an id
static member variable whose unique value is assigned by the Standard Library implementation when it is constructed during static initialization.boost::locale::generator::operator()
to generate a locale, it only installs the std::locale::facet
objects into the locale that have an id
member variable that is part of the same DLL or executable where that call is contained.Alternative Solution
std::locale::facet
objects from all DLLs and the executable using Boost.Locale get installed into the std::locale
object you're trying to use.DllMain
when its second parameter fdwReason
is DLL_PROCESS_ATTACH
, and for your executable, you could call it in WinMain
or some other application entry point (if you're using something like MFC or Qt).void setup_global_locale()
{
const boost::locale::generator generator;
const std::locale locale = generator.generate( std::locale(), "" );
std::locale::global( locale );
}
boost::locale::generator::operator()
will do, since it uses std::locale::classic
as the base locale, and that one cannot be modified. By calling this from each DLL and the executable, you'll install each of their std::locale::facet
objects into the global locale.