提升std :: wstring的C ++跨平台(Windows& Mac)序列化

时间:2011-12-12 21:47:54

标签: c++ serialization boost wofstream

我在一个为Windows(使用Visual Studio 2008)和Mac(使用GCC)构建的程序中使用Boost C ++库实现序列化。该程序在其大约30个类中使用宽字符串(std::wstring)。根据平台的不同,当我保存到文件(通过boost::archive::text_woarchive)时,宽字符串在输出文件中的表示方式不同。

保存在 Windows

H*e*l*l*o* *W*o*r*l*d*!* ...

保存在 MacOSX

H***e***l***l***o*** ***W***o***r***l***d***!*** ...

其中*是NULL字符。

当我尝试使用Mac版本读取在Windows下创建的文件时(反之亦然),我的程序崩溃了。

根据我的理解,到目前为止,Windows本身使用每个宽字符2个字节,而MacOSX(我认为通常使用Unix)使用4个字节。

我遇到了utf8_codecvt_facet.cppUTF8-CPPICUDinkumware等可能的解决方案,但是我还没有看到一个例子这将与我已经拥有的东西一起工作(例如,我不希望在此时重写五个月的序列化工作):

std::wofstream ofs( "myOutputFile" );
boost::archive::text_woarchive oa( ... );
//... what do I put here? ...
oa << myMainClass;

myMainClass包含宽字符串和Boost智能指针,这些指针反过来会被序列化。

2 个答案:

答案 0 :(得分:2)

wofstreamtypedef basic_ofstream<wchar_t, char_traits<wchar_t> > wofstream;

在Linux上,您需要声明一个自定义ofstream来处理16位字符(在Linux上)。 这可以按如下方式完成:

typedef std::uint16_t Char16_t;
typedef basic_ofstream<Char16_t, char_traits<Char16_t> > wofstream_16;

现在wofstream_16可以在不同平台上无缝使用,以处理16位宽字符。

答案 1 :(得分:0)

有一个简单的解决方案对我有用。这只是在official documentation中理解这些语句并将它们转换为C ++语法的问题:

  
      
  1. 打开一个宽字符流。
  2.   
  3. 更改流语言环境以使用boost :: archive :: codecvt_null
  4.   
  5. 使用标记no_codecvt创建存档。
  6.   

所以一起看起来像这样(输出到文件):

#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;

两个平台上的输出文件现在都相同,并存储为UTF8。