e-tipsmemo

ごった煮

Visual Studio 2017 boost xml serialization

Nuget パッケージマネージャーでboostと検索して
プロジェクトのプラットフォームツールセットのバージョンにあったBoostをインストールする

f:id:katakanan:20180630112732p:plain
今回はv140を入れた。

準備

シリアライズしたいクラスに追加する。

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>

class hoge
{
public:
	int a;
	std::string b;

private:
	friend class boost::serialization::access;
	template <class Archive>
	void serialize(Archive& archive, unsigned int version) 
	{
		archive& boost::serialization::make_nvp("a", a);
		archive& boost::serialization::make_nvp("b", b);
	}
};

メンバに自作の別のクラスがある場合は、そのクラスにも似たようにserialize関数を実装すると
再帰的にシリアライズされてくれる。

STLのクラスには自分で実装できないので
~~~.hppをincludeするとできる(例: boost/serialization/string.hpp )

利用

#include <boost/archive/xml_oarchive.hpp>//書き出し
#include <boost/archive/xml_iarchive.hpp>//読み込み

書き出し

hoge h;
//hに値をセットする
std::ofstream ofs(TEXT("test.xml"), std::ios::trunc);
{
	boost::archive::xml_oarchive oarchive(ofs);
	oarchive << boost::serialization::make_nvp("Root", h);
} //ファイルを閉じる前にスコープを区切る
ofs.close();

スコープを切らないと、多分oarchiveのデストラクタが呼ばれなくて(?)、xmlタグが正しく閉じられない。
間違った形のxmlをiarchiveで読もうとすると、
input stream errorでプログラムが止まる。

読み込み

std::ifstream ifs(TEXT("test.xml"));
if (ifs.fail())
{
	return false;
}
hoge h;
{
	boost::archive::xml_iarchive iarchive(ifs);
	iarchive >> boost::serialization::make_nvp("Root", h);
}
//hが読めているはず