如何让 boost::serialization 工作?
Posted
技术标签:
【中文标题】如何让 boost::serialization 工作?【英文标题】:how to get boost::serialization to work? 【发布时间】:2014-01-16 07:24:38 【问题描述】:我正在开发 ubuntu 12.04LTS 并使用 clang 3.4。
我有一个 CMake 项目并想使用 boost 序列化库。我从 SourceForge 下载了 boost 1.55.0。
我的项目文件夹树如下所示:
MyProject
| Source
| | main.cpp
| | CMakeLists.txt
| Build
| Libraries
| | Boost1p55p0
| | | boost
| | | ...other boost data
| | | build
| | | | include
| | | | lib
所以在Boost1p55p0
目录中我创建了一个新目录build
,所以引导程序看起来像:
./bootstrap.sh --prefix=build/
然后我做了
./b2
和
./b2 install
所以最小的不工作示例是:
CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
set( CMAKE_C_COMPILER clang )
set( CMAKE_CXX_COMPILER clang++ )
set( CMAKE_LINKER llvm-link )
project (Test)
include_directories( $PROJECT_SOURCE_DIR ../Libraries/Boost1p55p0/build/include )
set( sources $sources main )
add_executable(Test $sources)
set( OperatingSystem "Linux" )
set( CMAKE_CXX_FLAGS "-std=c++11" )
find_library( PATH_TO_BoostSerialization boost_serialization ../Libraries/Boost1p55p0/build/lib/ )
target_link_libraries (Test $PATH_TO_BoostSerialization)
main.cpp(来自tutorial,但带有 xml 档案):
#include <fstream>
#include <string>
// include headers that implement a archive in simple text format
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
ar & degrees;
ar & minutes;
ar & seconds;
int degrees;
int minutes;
float seconds;
public:
gps_position();
gps_position(int d, int m, float s) :
degrees(d), minutes(m), seconds(s)
;
int main()
std::string inFileName = "testIn.xml";
std::string outFileName = "testOut.xml";
// create and open a character archive for output
std::ofstream ofs(outFileName);
// create class instance
const gps_position g(35, 59, 24.567f);
// save data to archive
boost::archive::xml_oarchive oa(ofs);
// write class instance to archive
oa << g;
return 0;
现在我得到以下编译器错误:
[cut off directory tree here]Boost1p55p0/build/include/boost/archive/basic_xml_oarchive.hpp:92:9: error: no matching function for call to
'assertion_failed'
BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut off directory tree here]Boost1p55p0/build/include/boost/mpl/assert.hpp:287:11: note: expanded from macro 'BOOST_MPL_ASSERT'
boost::mpl::assertion_failed<false>( \
我不知道错误在哪里。如果我知道,我会很高兴。
在此先感谢
【问题讨论】:
【参考方案1】:啊,我刚刚注意到你在这里提到了唯一重要的一点,隐藏在一个小侧面:
main.cpp(来自教程,但带有 xml 档案)
Xml 档案的元素需要名称!
Name-Value Pairs
XML 档案有一种特殊的情况。 XML 格式具有嵌套结构,可以很好地映射到序列化系统使用的“递归类成员访问者”模式。但是,XML 与其他格式的不同之处在于它需要为每个类数据成员命名。我们的目标是将此信息添加到类序列化规范中,同时仍允许序列化代码与任何存档一起使用。
我们的解决方案是将要序列化的类成员包装在 name-value-pair 中。此结构在 nvp.hpp 中定义。它只是对数据成员的引用以及指向对应于 XML 名称的 const char * 的指针。它实现了名称-值对的默认序列化函数。此默认操作只是忽略项目名称并以正常方式序列化数据值。对于没有为名称-值对做出任何特殊规定的归档类,这是在名称-值对被序列化时将调用的操作。因此,将数据值包装成名称-值对在与没有为此包装器提供特殊规定的档案一起使用时将无效。
看,看demo_xml.cpp
,加:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
ar & BOOST_SERIALIZATION_NVP(degrees);
ar & BOOST_SERIALIZATION_NVP(minutes);
ar & BOOST_SERIALIZATION_NVP(seconds);
和
boost::archive::xml_oarchive oa(ofs);
// write class instance to archive
oa << BOOST_SERIALIZATION_NVP(g);
看Live on Coliru
输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<g class_id="0" tracking_level="0" version="0">
<degrees>35</degrees>
<minutes>59</minutes>
<seconds>24.566999</seconds>
</g>
</boost_serialization>
【讨论】:
谢谢。现在发布的代码有效。但我没有忘记提及:main.cpp (from the tutorial but with xml archives)
;)。但现在我想更进一步并补充说:gps_position newg; std::ifstream ifs(outFileName); boost::archive::xml_iarchive ia(ifs); ia >> newg;
。但是这个编译失败并出现完全相同的错误消息。那里有什么问题?现在Coliru ;)
@Rico-E 我终于注意到隐藏得很好的评论并且已经编辑了答案:)
我同意:它隐藏得很好;)抱歉,我根本不知道这是重要的一点。但是你能看看我的第一条评论,因为现在阅读 xml 档案失败了。我什至学会了使用 Coliru :)
嗯,如果它是完全相同的消息,那么,通常它是完全相同的问题:) 我已经修改了答案:coliru.stacked-crooked.com/a/7c21b376a5c468b3
太棒了!非常感谢!以上是关于如何让 boost::serialization 工作?的主要内容,如果未能解决你的问题,请参考以下文章
使用 boost::serialization 时如何刷新文件缓冲区?
如何抑制 boost serialization::archive 中的额外信息?
如何为 boost::serialization 指定一个 nvp 包装器?