增强C++;std::wstring的跨平台(Windows和Mac)序列化 我使用Boost C++库实现序列化,该程序是为Windows(使用Visual Studio 2008)和MAC(使用GCC)构建的程序。该程序在大约30个类中使用宽字符串(std::wstring)。根据平台的不同,当我保存到文件时(通过boost::archive::text\u woarchive),宽字符串在输出文件中的表示方式不同
保存在窗口下:增强C++;std::wstring的跨平台(Windows和Mac)序列化 我使用Boost C++库实现序列化,该程序是为Windows(使用Visual Studio 2008)和MAC(使用GCC)构建的程序。该程序在大约30个类中使用宽字符串(std::wstring)。根据平台的不同,当我保存到文件时(通过boost::archive::text\u woarchive),宽字符串在输出文件中的表示方式不同,c++,serialization,boost,wofstream,C++,Serialization,Boost,Wofstream,保存在窗口下: H*e*l*l*o* *W*o*r*l*d*!* ... H***e***l***l***o*** ***W***o***r***l***d***!*** ... #include <fstream> #include <locale> #include <boost/archive/codecvt_null.hpp> #include <boost/archive/text_woarchive.hpp> #include &
H*e*l*l*o* *W*o*r*l*d*!* ...
H***e***l***l***o*** ***W***o***r***l***d***!*** ...
#include <fstream>
#include <locale>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/text_woarchive.hpp>
#include <boost/archive/text_wiarchive.hpp>
// (1)
std::wofstream ofs( "myOutputFile.dat" );
// (2)
std::locale loc( ofs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ofs.imbue( loc );
// (3) (note text_woarchive)
boost::archive::text_woarchive oa( ofs, boost::archive::no_codecvt );
oa << myMainClass;
std::wifstream ifs( "myInputFile.dat" );
std::locale loc( ifs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ifs.imbue( loc );
boost::archive::text_wiarchive ia( ifs, boost::archive::no_codecvt );
ar >> myMainClass;
保存在MacOSX下:
H*e*l*l*o* *W*o*r*l*d*!* ...
H***e***l***l***o*** ***W***o***r***l***d***!*** ...
#include <fstream>
#include <locale>
#include <boost/archive/codecvt_null.hpp>
#include <boost/archive/text_woarchive.hpp>
#include <boost/archive/text_wiarchive.hpp>
// (1)
std::wofstream ofs( "myOutputFile.dat" );
// (2)
std::locale loc( ofs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ofs.imbue( loc );
// (3) (note text_woarchive)
boost::archive::text_woarchive oa( ofs, boost::archive::no_codecvt );
oa << myMainClass;
std::wifstream ifs( "myInputFile.dat" );
std::locale loc( ifs.getloc(), new boost::archive::codecvt_null<std::ostream::char_type>() );
ifs.imbue( loc );
boost::archive::text_wiarchive ia( ifs, boost::archive::no_codecvt );
ar >> myMainClass;
其中*为空字符
当我试图读取在Windows下使用Mac构建创建的文件时(反之亦然),我的程序崩溃
据我目前的理解,Windows在本机上每个宽字符使用2个字节,而MacOSX(我想一般是Unix)使用4个字节
我遇到过一些可能的解决方案,如utf8\u codecvt\u facet.cpp
、和,但是我还没有看到一个可以使用我已有的解决方案的示例(例如,我不希望在此时重新编写五个月的序列化工作):
std::wofstream of s(“myOutputFile”);
boost::archive::text_wo归档oa(…);
//... 我在这里放什么。。。
oawofstream
是流wofstream的typedef基本类型代码>
在linux上,您需要声明流的自定义
来处理16位字符(在linux上)。
这可以通过以下方式完成:
typedef std::uint16_t Char16_t;
typedef basic_ofstream<Char16_t, char_traits<Char16_t> > wofstream_16;
typedef std::uint16\u t Char16\u t;
流wofstream_16的类型DEF basic_;
现在,wofstream\u 16
可以在不同的平台上无缝使用,以处理16位宽的字符。有一个简单的解决方案适合我。这只是理解这些语句并将它们转换成C++语法:的问题。
打开一个宽字符流
更改流区域设置以使用boost::archive::codevt_null
创建带有no_codevt标志的存档
所以所有内容看起来都是这样的(输出到文件):
#包括
#包括
#包括
#包括
#包括
// (1)
std::wofstream ofs(“myOutputFile.dat”);
// (2)
std::locale loc(ofs.getloc(),new boost::archive::codevt_null());
ofs.imbue(loc);
//(3)(注:文本和存档)
boost::archive::text\u wo归档oa(ofs,boost::archive::no\u codecvt);
oa>mymain类;
现在,两个平台上的输出文件都是相同的,并存储为UTF8。有没有办法为wstring添加自己的加载和保存函数的专门化?这是什么意思?将序列化拆分为单独的load
和save
函数?我确实知道如何做到这一点,但如果我要编写这些函数,我不能确切地确定在wstring上执行哪种类型的转换。我会按照bames53的想法,为wstring编写boost::serialization例程的专门化。这样,您可以选择每个字符2或4个字节,并在两种平台上都使用它。@Tymek不,我提到的加载和保存功能只是偶然的。我的意思是您可以用自己的代码覆盖默认的序列化函数,例如,将wstring转换为UTF-8字符串进行序列化。例如,如果wstring序列化是通过模板实现的,则可以为wstring创建自己的模板专用化。您必须决定交换格式(UTF-8、UTF-16、UTF-16BE、UTF16-LE、UTF32…。谢谢vine的帮助。我试图添加此内容,但遇到编译问题:错误:调用boost::archive::text\u woarchive::text\u woarchive(SaveSession()::wofstream\u 16&)时没有匹配的函数。
<代码>候选项是:boost::archive::text\u woarchive::text\u woarchive(std::wostream&,unsigned int)
<代码>boost::archive::text\u woarchive::text\u woarchive(const boost::archive::text\u woarchive&)
有什么想法吗?我想你需要添加一个重载