
Hi folks Currently I’m having quite some trouble with the boost serialization library. Take the following classes as given: ProtocolFactory.h: #ifndef PROTOCOLFACTORY_H_ #define PROTOCOLFACTORY_H_ #include <boost/serialization/access.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/shared_ptr.hpp> class Meter; typedef boost::shared_ptr<Meter> MeterPtr; class MeteringProtocol; typedef boost::shared_ptr<MeteringProtocol> MeteringProtocolPtr; class ProtocolFactory { public: ProtocolFactory(); virtual ~ProtocolFactory(); virtual MeteringProtocolPtr getNewProtocolInstance(Meter *const) const = 0; virtual MeteringProtocolPtr getNewProtocolInstance(const MeterPtr &) const = 0; private: friend class boost::serialization::access; template<class archive> void serialize(archive &, const unsigned int) { } }; BOOST_IS_ABSTRACT(ProtocolFactory); typedef boost::shared_ptr<ProtocolFactory> ProtocolFactoryPtr; #endif /*PROTOCOLFACTORY_H_*/ ProtocolFactory.cpp #include "ProtocolFactory.h" ProtocolFactory::ProtocolFactory() { } ProtocolFactory::~ProtocolFactory() { } Iec1107OverSerialFactory.h #ifndef IEC1107OVERSERIALFACTORY_H_ #define IEC1107OVERSERIALFACTORY_H_ #include "ProtocolFactory.h" class Iec1107OverSerialFactory : public ProtocolFactory { public: Iec1107OverSerialFactory(); virtual ~Iec1107OverSerialFactory(); virtual MeteringProtocolPtr getNewProtocolInstance(Meter *const) const; virtual MeteringProtocolPtr getNewProtocolInstance(const MeterPtr &) const; private: friend class boost::serialization::access; template<class archive> void serialize(archive &, const unsigned int); }; #include "Iec1107OverSerialFactory.inc" typedef boost::shared_ptr<Iec1107OverSerialFactory> Iec1107OverSerialFactoryPtr; #endif /*IEC1107OVERSERIALFACTORY_H_*/ Iec1107OverSerialFactory.inc: #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/nvp.hpp> BOOST_CLASS_EXPORT(Iec1107OverSerialFactory) // Boost must include Serialization info for this class even if its not directly referencd (e.g. by its base class) template<class Archive> void Iec1107OverSerialFactory::serialize(Archive &ar, const unsigned int version) { using boost::serialization::make_nvp; ar & make_nvp("ProtocolFactory", boost::serialization::base_object<ProtocolFactory>(*this)); } Iec1107OverSerialFactory.cpp: #include "Iec1107OverSerialFactory.h" #include "Iec1107OverSerial.h" #include "../Meter.h" #include "MeteringProtocol.h" using namespace boost; Iec1107OverSerialFactory::Iec1107OverSerialFactory() { } Iec1107OverSerialFactory::~Iec1107OverSerialFactory() { } MeteringProtocolPtr Iec1107OverSerialFactory::getNewProtocolInstance( Meter *const target) const { return MeteringProtocolPtr(new Iec1107OverSerial(target)); } MeteringProtocolPtr Iec1107OverSerialFactory::getNewProtocolInstance( const MeterPtr &target) const { return MeteringProtocolPtr(new Iec1107OverSerial(target)); } MeteringProtocolCompoisteFactory.h #ifndef METERINGPROTOCOLCOMPOSITEFACTORY_H_ #define METERINGPROTOCOLCOMPOSITEFACTORY_H_ #include "ProtocolFactory.h" #include <vector> class MeteringProtocolCompositeFactory : public ProtocolFactory { public: MeteringProtocolCompositeFactory(const std::vector<ProtocolFactoryPtr> &); virtual ~MeteringProtocolCompositeFactory(); virtual MeteringProtocolPtr getNewProtocolInstance(Meter *const) const; virtual MeteringProtocolPtr getNewProtocolInstance(const MeterPtr &) const; const std::vector<ProtocolFactoryPtr> &getFactories() const; private: std::vector<ProtocolFactoryPtr> factories; friend class boost::serialization::access; template<class archive> void serialize(archive &, const unsigned int); }; #include "MeteringProtocolCompositeFactory.inc" typedef boost::shared_ptr<MeteringProtocolCompositeFactory> MeteringProtocolCompositeFactoryPtr; #endif /*METERINGPROTOCOLCOMPOSITEFACTORY_H_*/ MeteringProtocolCompoisteFactory.inc #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/nvp.hpp> BOOST_CLASS_EXPORT(MeteringProtocolCompositeFactory) // Boost must include Serialization info for this class even if its not directly referencd (e.g. by its base class) namespace boost { namespace serialization { template<class Archive> inline void save_construct_data(Archive &ar, const MeteringProtocolCompositeFactory *pf, const unsigned int version) { using boost::serialization::make_nvp; ar & make_nvp("IncludedProtocols", pf->getFactories()); } template<class Archive> inline void load_construct_data(Archive &ar, MeteringProtocolCompositeFactory *pf, const unsigned int version) { using boost::serialization::make_nvp; std::vector<ProtocolFactoryPtr> factories; ar & make_nvp("IncludedProtocols", factories); ::new(pf)MeteringProtocolCompositeFactory(factories); } } } template<class Archive> void MeteringProtocolCompositeFactory::serialize(Archive &ar, const unsigned int version) { using boost::serialization::make_nvp; ar & make_nvp("ProtocolFactory", boost::serialization::base_object<ProtocolFactory>(*this)); } MeteringProtocolCompositeFactory.cpp: #include "MeteringProtocolCompositeFactory.h" #include "MeteringProtocolComposite.h" #include <iterator> using namespace std; MeteringProtocolCompositeFactory::MeteringProtocolCompositeFactory( const vector<ProtocolFactoryPtr> &factories) : factories(factories) { } MeteringProtocolCompositeFactory::~MeteringProtocolCompositeFactory() { } MeteringProtocolPtr MeteringProtocolCompositeFactory::getNewProtocolInstance( Meter *const target) const { vector<MeteringProtocolPtr> protocols; for (vector<ProtocolFactoryPtr>::const_iterator it = factories.begin(); it != factories.end(); ++it) { protocols.push_back((*it)->getNewProtocolInstance(target)); } return MeteringProtocolPtr(new MeteringProtocolComposite(protocols)); } MeteringProtocolPtr MeteringProtocolCompositeFactory::getNewProtocolInstance( const MeterPtr &target) const { vector<MeteringProtocolPtr> protocols; for (vector<ProtocolFactoryPtr>::const_iterator it = factories.begin(); it != factories.end(); ++it) { protocols.push_back((*it)->getNewProtocolInstance(target)); } return MeteringProtocolPtr(new MeteringProtocolComposite(protocols)); } const std::vector<ProtocolFactoryPtr> &MeteringProtocolCompositeFactory::getFactories() const { return factories; } MeterType.h: #ifndef METERTYPE_H_ #define METERTYPE_H_ #include <boost/serialization/access.hpp> #include <boost/shared_ptr.hpp> #include <string> #include <vector> class ProtocolFactory; typedef boost::shared_ptr<ProtocolFactory> ProtocolFactoryPtr; class MeterType { public: MeterType(const std::string &, const std::vector<std::string> &, const ProtocolFactoryPtr &); virtual ~MeterType(); const std::string &getTypeName() const; const std::vector<std::string> &getRequestedDataItems() const; const ProtocolFactoryPtr &getSupportedProtocols() const; private: MeterType(); std::string typeName; std::vector<std::string> requestedDataItems; // include Data IDs like 1.8.1, standardized for all metering protocls (I hope :) // TODO: Create ProtocolFactoryComposite, including a serialization // TODO: Serialize supportedProtcols and add to constructor ProtocolFactoryPtr supportedProtocols; friend class boost::serialization::access; template<class archive> void serialize(archive &, const unsigned int); }; #include "MeterType.inc" typedef boost::shared_ptr<MeterType> MeterTypePtr; #endif /*METERTYPE_H_*/ MeterType.inc: #include <boost/serialization/nvp.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> #include <iostream> namespace boost { namespace serialization { template<class Archive> inline void save_construct_data(Archive &ar, const MeterType *t, const unsigned int version) { using boost::serialization::make_nvp; ar & make_nvp("TypeName", t->getTypeName()); ar & make_nvp("RequestedDataItems", t->getRequestedDataItems()); ar & make_nvp("SupportedProtocols", t->getSupportedProtocols()); } template<class Archive> inline void load_construct_data(Archive &ar, MeterType *t, const unsigned int version) { using boost::serialization::make_nvp; std::string typeName; std::vector<std::string> requestedDataItems; ProtocolFactoryPtr supportedProtocols; ar & make_nvp("TypeName", typeName); ar & make_nvp("RequestedDataItems", requestedDataItems); ar & make_nvp("SupportedProtocols", supportedProtocols); ::new(t)MeterType(typeName, requestedDataItems, supportedProtocols); } } } template<class Archive> void MeterType::serialize(Archive &ar, const unsigned int version) { } MeterType.cpp: #include "MeterType.h" using namespace std; MeterType::MeterType(void) { } MeterType::MeterType(const string &typeName, const vector<string> &requestedDataItems, const ProtocolFactoryPtr &supportedProtocols) : typeName(typeName), requestedDataItems(requestedDataItems), supportedProtocols(supportedProtocols) { } MeterType::~MeterType() { } const string &MeterType::getTypeName() const { return typeName; } const vector<string> &MeterType::getRequestedDataItems() const { return requestedDataItems; } const ProtocolFactoryPtr &MeterType::getSupportedProtocols() const { return supportedProtocols; } Phew. Quite a list, I know :) . Anyway, to serialize these classes, I wrote the following code: { ofstream ofs("testIt.xml"); archive::xml_oarchive oxml(ofs); oxml << serialization::make_nvp("supportedProtocols", iec1107); } ProtocolFactoryPtr newProtocolFactory; ifstream ifs("testIt.xml"); archive::xml_iarchive ixml(ifs); ixml >> serialization::make_nvp("supportedProtocols", newProtocolFactory); which, however, throws an assert-failure in „basic_iarchive.cpp“ at line 390. Uncommenting that line and recompiling allows me to fully and correctly execute the above code. However, when trying this: { ofstream ofs("testIt.xml"); archive::xml_oarchive oxml(ofs); oxml << serialization::make_nvp("ZMD120", zmd120); } MeterTypePtr newType; ifstream ifs("testIt.xml"); archive::xml_iarchive ixml(ifs); ixml >> serialization::make_nvp("ZMD120", zmd120); The Program crashes with a segmentation fault. Using Insight, i found the very line this happens: It’s in „MeterType.inc“ at line 22: „ar & make_nvp(„SupportedProtocols“, supportedProtocols); Since I imagine this to be more or less exactly the same code as I executed before, without the MeterType class, I’m not quite sure why this should fail. Anyway, can anyone lend me a hand here? Firstly, why would the assertion error occur? And why does serializing ProtocolFactoryPtr one time work and another time fail? Thank you for any help and best regards Kessi _________________________________________________________________ Drück deine Gefühle aus! Hol dir 30 GRATIS Emoticons für den Windows Live Messenger! http://get.live.com