I created a small sample for testing the boost serialization library, but I have a compilation problem.
First of all, here's the code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <boost/filesystem/operations.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/version.hpp>
std::vector<uint8_t> buf;
class MyClass
{
public:
MyClass(){};
virtual ~MyClass(){};
int assetStatus;
friend class boost::serialization::access;
template<typename Archive> void serialize(
Archive & ar,
const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(assetStatus);
}
std::string ToString()
{
std::string toret;
toret += " assetStatus: " + assetStatus;
return toret;
}
};
int main()
{
MyClass a, b;
a.assetStatus = 10;
std::cout << a.ToString();
boost::archive::xml_oarchive ooxml(std::ofstream(dbPath));
ooxml << BOOST_SERIALIZATION_NVP(a); // error here
MyClass d;
boost::archive::xml_iarchive iixml(std::ifstream(dbPath));
iixml >> BOOST_SERIALIZATION_NVP(d); // error here
std::cout << d.ToString();
}
I get a compilation error at the lines:
ooxml << BOOST_SERIALIZATION_NVP(a);
and
iixml >> BOOST_SERIALIZATION_NVP(d);
The error is:
no match for operator>> in 'iixml >> boost::serialization::make_nvp(const char*, T&) [with T=MyClass(((MyClass&)(&d)))]'
Do you have any idea regarding the meaning of this?
It looks like dbPath is not defined. Additionally, the declaration of ooxml/iixml appears incorrect.
Try modifying your code to do the following:
...
const char * dbPath = "file.xml"
std::ofstream ofs(dbPath);
boost::archive::xml_oarchive ooxml(ofs);
ooxml << BOOST_SERIALIZATION_NVP(a);
std::ifstream ifs(dbPath);
boost::archive::xml_iarchive iixml(ofs);
iixml >> BOOST_SERIALIZATION_NVP(d);
I think NVP (name value pair) is not supported for reading (i.e. with iixml), either use & (instead of >>) or iixml >> d;
Related
I am attempting to serialize a class which contains a boost::container::string
#include <iostream>
#include <cstdlib>
#include <boost/container/string.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
class car
{
public:
car() {}
car(boost::container::string make) : make(make) {}
boost::container::string make;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & make;
}
};
int main()
{
car my_car("ford");
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << my_car;
car new_car;
boost::archive::text_iarchive ia(ss);
ia >> new_car;
}
But the above fails to compile with the following error:
boost/serialization/access.hpp:116:11: error: 'class boost::container::basic_string<char>' has no member named 'serialize'
The same code can be changed to use std::string and it compiles fine.
Can boost::container::strings be serialized and if so what am I doing incorrectly or missing?
Yes. Surprisingly, the necessary support is not baked into Boost. Though if you look inside the string serialization header you will find that it has support as "primitive", and it takes just one line to enable it:
BOOST_CLASS_IMPLEMENTATION(boost::container::string, boost::serialization::primitive_type)
Now it works the same as std::string:
Live On Coliru
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/container/string.hpp>
#include <iostream>
BOOST_CLASS_IMPLEMENTATION(boost::container::string, boost::serialization::primitive_type)
struct car {
template<class Ar> void serialize(Ar& ar, unsigned) { ar & make; }
boost::container::string make;
};
int main() {
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
car my_car{"ford"};
oa << my_car;
} // close archive
std::cout << ss.str() << "\n";
boost::archive::text_iarchive ia(ss);
car new_car;
ia >> new_car;
}
Prints
22 serialization::archive 17 0 0 ford
The code below serialises and de serialises the class and structure's members.
The serialisation is working but i have encountered the below error while trying to deserialise it using oarch >> BOOST_SERIALIZATION_NVP(outObj);
Is there any big miss in the code that i have not realiased and not implemented .
In file included from main.cpp:1:
In file included from /usr/local/include/boost/archive/binary_oarchive.hpp:21:
In file included from /usr/local/include/boost/archive/binary_oarchive_impl.hpp:22:
In file included from /usr/local/include/boost/archive/basic_binary_oarchive.hpp:33:
In file included from /usr/local/include/boost/archive/detail/common_oarchive.hpp:22:
In file included from /usr/local/include/boost/archive/detail/interface_oarchive.hpp:23:
In file included from /usr/local/include/boost/archive/detail/oserializer.hpp:68:
/usr/local/include/boost/archive/detail/check.hpp:162:5: error: static_assert failed "typex::value"
BOOST_STATIC_ASSERT(typex::value);
^ ~~~~~~~~~~~~
/usr/local/include/boost/static_assert.hpp:70:41: note: expanded from macro 'BOOST_STATIC_ASSERT'
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <map>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_member.hpp>
struct values
{
std::string name;
std::string sex;
values():name("dummy"),sex("dummy"){} ;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(sex);
}
};
class Myclass
{
public:
Myclass()
{
values val1;
e_group.insert( std::make_pair(1,val1) ) ;
e_group.insert( std::make_pair(2,val1) ) ;
p_group.insert( std::make_pair(1,e_group) ) ;
p_group.insert( std::make_pair(2,e_group) ) ;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int version) const
{
ar & BOOST_SERIALIZATION_NVP(e_group);
ar & BOOST_SERIALIZATION_NVP(p_group);
}
typedef std::map<int,values> groups;
typedef std::map<int,groups> Pgroups;
groups e_group;
Pgroups p_group;
};
int main()
{
Myclass assetlist;
auto os = std::ostringstream(std::ios::binary);
boost::archive::binary_oarchive arch( os, boost::archive::no_header);
arch << BOOST_SERIALIZATION_NVP(assetlist);
std::string s1 = os.str();
std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
Myclass outObj;
boost::archive::binary_iarchive iarch (is , boost::archive::no_header );
iarch >> BOOST_SERIALIZATION_NVP(outObj);
return 0;
}
Your static assert fails because of the extra 'const' in Myclass::serialize function.
It should look like:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{ ... }
Conserning the BOOST_SERIALIZATION_NVP() usage see this question.
I am trying to store a User object and then read the stored object using the boost serialization library and VS2015 community. I followed the tutorial here. Currently the read/write object to file works just fine; however, after reading the object back in I cannot access any of the objects members (i.e. username and pw_hash). Is there something I am missing? I have seen tons of questions how to write/read the object using the library but none that show anyone accessing the objects members after reading the object from file.
Class:
#ifndef USER_H
#define USER_H
#include <fstream>
#include <string>
#include <boost\serialization\string.hpp>
#include <boost\archive\text_oarchive.hpp>
#include <boost\archive\text_iarchive.hpp>
#include "Hash.h"
class User
{
public:
User();
User(std::string & name, std::string & pwd);
~User();
private:
std::string pw_hash;
std::string username;
inline std::string get_username();
inline void set_username(const std::string & name);
inline std::string get_PwHash();
inline void set_PwHash(const std::string & hash);
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & username;
ar & pw_hash;
}
};
#endif
Below is where I encounter my problem. After the object is read from memory, VS2015 underlines test2.get_username() saying it is inaccessible.
Implementation:
#include "User.h"
int main(int argc, char *argv[])
{
User test("User1", "Password");
std::cout << test.get_username() << std::endl;
{
std::ofstream ofs("User1");
boost::archive::text_oarchive oa(ofs);
oa << test;
}
User test2();
{
std::ifstream ifs(username);
boost::archive::text_iarchive ia(ifs);
ia >> test2;
//error
std::cout << test2.get_username() << std::endl;
}
return 0;
}
Can anyone tell me why the below piece of code I wrote when compiling keeps complaining istream_iterator is not a member of std please can you tell?
Thanks guys
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <fstream>
//#include<sstream>
struct field_reader: std::ctype<char> {
field_reader(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(table_size, std::ctype_base::mask());
rc[';'] = std::ctype_base::space;
return &rc[0];
}
};
struct Stud{
double VehicleID;
double FinancialYear;
double VehicleType;
double Manufacturer;
double ConditionScore;
friend std::istream &operator>>(std::istream &is, Stud &s) {
return is >> s.VehicleID >> s.FinancialYear >> s.VehicleType >> s.Manufacturer >> s.ConditionScore;
}
// we'll also add an operator<< to support printing these out:
friend std::ostream &operator<<(std::ostream &os, Stud const &s) {
return os << s.VehicleID << "\t"
<< s.FinancialYear << "\t"
<< s.VehicleType << "\t"
<< s.Manufacturer << "\t"
<< s.ConditionScore;
}
};
int main(){
// Open the file:
std::ifstream in("VehicleData_cs2v_1.csv");
// Use the ctype facet we defined above to classify `;` as white-space:
in.imbue(std::locale(std::locale(), new field_reader));
// read all the data into the vector:
std::vector<Stud> studs{(std::istream_iterator<Stud>(in)),
std::istream_iterator<Stud>()};
// show what we read:
for (auto s : studs)
std::cout << s << "\n";
}
So please if you spot the issue let me know as I can't quite tell at the moment and I believe I put in all the necessary include libraries
The error message may sound a bit misleading, but it's the best thing the compiler could say. std::istream_iterator is declared in the <iterator> header file, that's what causes your problem.
Just add this to your includes
#include <iterator>
I'm very new to Boost serialization. I'm using Boost to serialize a Xml document:
typedef struct xmllist
{
std::string Name;
int Param;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(Name);
ar & BOOST_SERIALIZATION_NVP(Param);
}
} XMLLIST;
void XmlWrite()
{
std::ofstream ofs("xmlfile.xml");
assert(ofs.good());
boost::archive::xml_oarchive oa(ofs);
XMLLIST xmllist;
xmllist.Name = "Name";
xmllist.Param = 1;
oa << BOOST_SERIALIZATION_NVP(xmllist);
}
boost::archive::xml_oarchive oa(ofs) is giving me Run-Time Check Failure #2 - Stack around the variable 'oa' was corrupted.
I'm using Microsoft Visual Studio 2010 and boost_1_56_0.
Can someone please help me in this issue?
My opinion that the stack corruption happens not in the provided code but somewhere else. The slightly modified code, which I provided below, works without any error under MSVC++ 2013 and Boost 1.57. Also it works fine on coliru.
#include <string>
#include <sstream>
#include <iostream>
#include <ostream>
#include <cassert>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/access.hpp>
struct CXMLList {
std::string Name;
int Param;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_NVP(Name);
ar & BOOST_SERIALIZATION_NVP(Param);
}
};
int main(int argc, char* argv[]) {
std::ostringstream ofs;
boost::archive::xml_oarchive oa(ofs);
CXMLList xmllist;
xmllist.Name = "Name";
xmllist.Param = 1;
oa << BOOST_SERIALIZATION_NVP(xmllist);
std::cout << "XML is:" << std::endl;
std::cout << ofs.str() << std::endl;
return 0;
}