Skip to main content
GameDev.net gamedev.net
🔒 Locked

Boost Serialization

Started by gorogoro Jan 4, 2007 at 12:13 PM 4 replies 8.1k views
Original Post
gorogoro
gorogoro
Hi Folks. I'm trying to use the boost serialization library but I'm gettin an error on a very simple example :/ here is the code: file --> main2.cpp


#include "core/system/Precompiled.h"

#include "core/DefaultTask.h"

#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>


	class A
	{
	private:
		friend class boost::serialization::access;

		template<class Archive>
		void serialize(Archive & ar, const unsigned int version)
		{
			ar & dumgf;
			ar & dumbi;
		}
	public:	
		int dumbi;
		float dumbf;
		A():dumbi(12), dumbf(69.69f){ }
		A(int dumb1, float dumb2) : dumbi(dumb1), dumbf(dumb2){ }
	};

class SilvTask : public DefaultTask
	{
	private:
		typedef DefaultTask Parent;
	
		int dumbi;
		float dumbf;
		A testA;

		bool m_save, m_xml;
		std::string m_filename;

	public:
		SilvTask():m_save(false), dumbf(69.69f), dumbi(7), m_xml(false)
		{			

		}

		int SilvTask::ParseArguments(const std::vector<std::string>& args)
		{
			for(uint32 i = 0; i < (uint32)args.size(); i++)
			{
				if(args.find("-xml"))
					m_xml = true;

				if(args.find("-save=") != std::string::npos)
				{
					m_filename = args.substr(6);
					m_save = true;
				}
				else if(args.find("-load=") != std::string::npos)
				{
					m_filename = args.substr(6);
					m_save = false;
				}
			}

			return FE_OK;
		}

		int SilvTask::LoadData()
		{
			if(m_save)
				WriteObject();
			else
				LoadObject();

			return FE_OK;			
		}

		int SilvTask::WriteObject()
		{
			A aux(12, 69.69f);
			// create and open a character archive for output
			std::ofstream ofs(m_filename.c_str());
			boost::archive::text_oarchive oa(ofs);
			//write class instance to archive
			oa << aux;

			return FE_OK;
		}

		int SilvTask::LoadObject()
		{
			A newAux;
			std::ifstream ifs(m_filename.c_str(), std::ios::binary);
			boost::archive::text_iarchive ia(ifs);
			// read class state from archive
			ia >> newAux;

			return FE_OK;
		}
};





and here is the error:
Quote:
3rdparty\include\boost\archive\detail\oserializer.hpp(567) : error C2027: use of undefined type 'boost::STATIC_ASSERTION_FAILURE' with [ x=false ] 3rdparty\include\boost\archive\basic_text_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::save(Archive &,T &)' being compiled with [ Archive=boost::archive::text_oarchive, T=FlowEngine::A ] 3rdparty\include\boost\archive\detail\interface_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::basic_text_oarchive::save_override(T &,int)' being compiled with [ Archive=boost::archive::text_oarchive, T=FlowEngine::A ] samples\silvestre\main2.cpp(122) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_oarchive::operator <<(T &)' being compiled with [ Archive=boost::archive::text_oarchive, T=FlowEngine::A ]
Any ideias??? Thanks!
Nitage
Nitage
That means your code failed a compile time assertion check.

Look at boost\archive\detail\oserializer.hpp line 567 to see which condition you violated.
gorogoro
gorogoro
I've been that already, but I don't get the error. I'm doing everything like the examples provided by boost.

I'v notest the comment at that line to:

template<class Archive, class T>inline void save(Archive & ar, T &t){    // if your program traps here, it indicates taht your doing one of the following:    // a) serializing an object of a type marked "track_never" through a pointer.    // b) saving an non-const object of a type not markd "track_never)    // Either of these conditions may be an indicator of an error usage of the    // serialization library and should be double checked.  See documentation on    // object tracking.    BOOST_STATIC_ASSERT(check_tracking<T>::value);        save(ar, const_cast<const T &>(t));}


And I've tried to put that boost tracking stuff but then I get a syntax error :S.
ARGH!

Here is the code I've put:

class A	{	public:		//friend class serialization::access;				template<class Archive>		void serialize(Archive & ar, const unsigned int version)		{						ar & dumbf;			ar & dumbi;		}				int dumbi;		float dumbf;		A():dumbi(12), dumbf(69.69f){ }		A(int dumb1, float dumb2) : dumbi(dumb1), dumbf(dumb2){ }	};    BOOST_CLASS_TRACKING(A, track_always)............


And here is the error:

Quote:

error C2143: syntax error : missing ';' before '<'
error C2913: explicit specialization; 'FlowEngine::boost::serialization::tracking_level' is not a specialization of a class template
error C2059: syntax error : '<'
error C2143: syntax error : missing ';' before '{'
error C2447: '{' : missing function header (old-style formal list?)


The code of that define is:

#define BOOST_CLASS_TRACKING(T, E)           namespace boost {                            namespace serialization {                    template<>                                   struct tracking_level< T >                   {                                                typedef mpl::integral_c_tag tag;             typedef mpl::int_< E> type;                  BOOST_STATIC_CONSTANT(                           int,                                         value = tracking_level::type::value      );                                           /* tracking for a class  */                  BOOST_STATIC_ASSERT((                            mpl::greater<                                    /* that is a prmitive */                     implementation_level< T >,                   mpl::int_<primitive_type>                >::value                                 ));                                      };                                                                            
xen2
xen2
That's because you used the macro to define tracking level inside your namespace.
Just do it after your namespace and it should be fine.
-----Entropia 3D Engine Project, a next-gen and flexible C# 3D Engine under GPL.
gorogoro
gorogoro
Yeas! That it true! It seems that I can't put it inside my namespace.

But beside that I have something wrong, and I can't get what it is. I have 3 classes to test this: A;B and C inside the namespace FlowEngine as you can see:

#include "core/system/Precompiled.h"#include "core/DefaultTask.h"#include <fstream>#include <boost/archive/text_oarchive.hpp>#include <boost/archive/text_iarchive.hpp>#include <boost/serialization/tracking.hpp>#include <boost/serialization/split_member.hpp>namespace FlowEngine{class A;class C{public:	std::string text;	A* m_owner;	C():m_owner(0)	{		text = "Ola sua puta rabeta!";	}	template<class Archive>	void serialize(Archive & ar, const unsigned int version)	{					ar & text;		ar & m_owner;	}};class A{public:	friend class boost::serialization::access;		/*	template<class Archive>	void load(Archive & ar, const unsigned int file_version )	{		ar & dumbf;		ar & dumbi;		ar & testing;	}	template<class Archive>	void save(Archive & ar, const unsigned int file_version )	{		ar & dumbf;		ar & dumbi;		ar & testing;	}	template<class Archive>	void serialize(Archive & ar, const unsigned int file_version)	{			boost::serialization::split_member(ar, *this, file_version);	}	*/	template<class Archive>	void serialize(Archive & ar, const unsigned int version)	{					ar & dumbf;		ar & dumbi;		ar & testing;	}			int dumbi;	float dumbf;	C* testing;	A():dumbi(12), dumbf(69.69f)	{ 		testing = FE_NEW C();			testing->m_owner = this;	}	A(int dumb1, float dumb2) : dumbi(dumb1), dumbf(dumb2)	{ 		testing = FE_NEW C();		testing->m_owner = this;	}};class B : public A{private:	int dumbBi;	float dumbBf;public:	B():dumbBi(9), dumbBf(0.9876f)	{	}};class SilvTask : public DefaultTask{private:	typedef DefaultTask Parent;	int dumbi;	float dumbf;	A testA;	A* testAPointer;	bool m_save, m_xml;	std::string m_filename;public:	SilvTask():m_save(false), dumbf(69.69f), dumbi(7), m_xml(false),testAPointer(0)	{				}	int SilvTask::ParseArguments(const std::vector<std::string>& args)	{		for(uint32 i = 0; i < (uint32)args.size(); i++)		{			if(args.find("-xml"))				m_xml = true;			if(args.find("-save=") != std::string::npos)			{				m_filename = args.substr(6);				m_save = true;			}			else if(args.find("-load=") != std::string::npos)			{				m_filename = args.substr(6);				m_save = false;			}		}		return FE_OK;	}	int SilvTask::LoadData()	{		//BOOST_CLASS_TRACKING(A, track_never)		if(m_save)			WriteObject();		else			LoadObject();		return FE_OK;				}	int SilvTask::WriteObject()	{		A aux(12356, 8956.69f);			testAPointer = FE_NEW A(987, 123.56987f);		// create and open a character archive for output		std::ofstream ofs(m_filename.c_str());		boost::archive::text_oarchive oa(ofs);						//write class instance to archive		oa & testAPointer;		return FE_OK;	}	int SilvTask::LoadObject()	{		//A newAux;		std::ifstream ifs(m_filename.c_str(), std::ios::binary);		boost::archive::text_iarchive ia(ifs);		//ios::binary ia(ifs);		// read class state from archive		ia & testAPointer;		return FE_OK;	}	int SilvTask::CreateRenderEffects()	{		return FE_OK;	}	int OnStart(Mutex* mutex)	{		return FE_OK;	}};int FlowMain(const std::vector<std::string>& cmdLine){	if(cmdLine.size() < 1)	{		FE_LOG_ERROR(FE_INVALIDPARAM, "Please insert the file to read from!");		return FE_INVALIDPARAM;	}	SilvTask* task = FE_NEW SilvTask();	int r = task->ParseArguments(cmdLine);	if (FE_FAILED(r))	{		FE_DELETE task;		return r;	}	FlowCore::GetScheduler().RegisterTask(task, "silver Task", 0, .0f, .0f);	FE_DELETE task;	return FE_OK;}}//BOOST_CLASS_TRACKING(FlowEngine::A, boost::serialization::track_always);


Now if take the comments of class A to split member serialization I get this compile errors:

Quote:

\3rdparty\include\boost\serialization\access.hpp(93) : error C2662: 'void FlowEngine::A::save(Archive &,const unsigned int)' : cannot convert 'this' pointer from 'const FlowEngine::A' to 'FlowEngine::A &'
with
[
Archive=boost::archive::text_oarchive
]
Conversion loses qualifiers
\3rdparty\include\boost\serialization\split_member.hpp(43) : see reference to function template instantiation 'void boost::serialization::access::member_save(Archive &,T &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\serialization\split_member.hpp(42) : while compiling class template member function 'void boost::serialization::detail::member_saver::invoke(Archive &,const T &,const unsigned int)'
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\serialization\split_member.hpp(69) : see reference to class template instantiation 'boost::serialization::detail::member_saver' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\samples\silvestre\main2.cpp(82) : see reference to function template instantiation 'void boost::serialization::split_member(Archive &,T &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\serialization\access.hpp(109) : see reference to function template instantiation 'void FlowEngine::A::serialize(Archive &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive
]
\3rdparty\include\boost\serialization\serialization.hpp(81) : see reference to function template instantiation 'void boost::serialization::access::serialize(Archive &,T &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\serialization\serialization.hpp(140) : see reference to function template instantiation 'void boost::serialization::serialize(Archive &,T &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(152) : see reference to function template instantiation 'void boost::serialization::serialize_adl(Archive &,T &,const unsigned int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(145) : while compiling class template member function 'void boost::archive::detail::oserializer::save_object_data(boost::archive::detail::basic_oarchive &,const void *) const'
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(163) : see reference to class template instantiation 'boost::archive::detail::oserializer' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(162) : while compiling class template member function 'const boost::archive::detail::basic_oserializer &boost::archive::detail::pointer_oserializer::get_basic_serializer(void) const'
with
[
T=FlowEngine::A,
Archive=boost::archive::text_oarchive
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(515) : see reference to class template instantiation 'boost::archive::detail::pointer_oserializer' being compiled
with
[
T=FlowEngine::A,
Archive=boost::archive::text_oarchive
]
\3rdparty\include\boost\archive\detail\interface_oarchive.hpp(58) : see reference to function template instantiation 'const boost::archive::detail::basic_pointer_oserializer &boost::archive::detail::instantiate_pointer_oserializer(Archive *,T *)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(344) : see reference to function template instantiation 'const boost::archive::detail::basic_pointer_oserializer *boost::archive::detail::interface_oarchive::register_type(const T *)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(343) : while compiling class template member function 'const boost::archive::detail::basic_pointer_oserializer *boost::archive::detail::save_pointer_type::non_abstract::register_type(Archive &)'
with
[
Archive=boost::archive::text_oarchive,
TPtr=FlowEngine::A *,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(360) : see reference to class template instantiation 'boost::archive::detail::save_pointer_type::non_abstract' being compiled
with
[
Archive=boost::archive::text_oarchive,
TPtr=FlowEngine::A *,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(460) : see reference to function template instantiation 'const boost::archive::detail::basic_pointer_oserializer *boost::archive::detail::save_pointer_type::register_type(Archive &,T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
TPtr=FlowEngine::A *,
T=FlowEngine::A
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(447) : while compiling class template member function 'void boost::archive::detail::save_pointer_type::invoke(Archive &,const TPtr)'
with
[
Archive=boost::archive::text_oarchive,
TPtr=FlowEngine::A *
]
\3rdparty\include\boost\archive\detail\oserializer.hpp(536) : see reference to class template instantiation 'boost::archive::detail::save_pointer_type' being compiled
with
[
Archive=boost::archive::text_oarchive,
TPtr=FlowEngine::A *
]
\3rdparty\include\boost\archive\basic_text_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::save(Archive &,const T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]
\3rdparty\include\boost\archive\detail\interface_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::basic_text_oarchive::save_override(T &,int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]
\3rdparty\include\boost\archive\detail\interface_oarchive.hpp(86) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_oarchive::operator <<(T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]
\samples\silvestre\main2.cpp(190) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_oarchive::operator &(T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]



and if change the & operator for the << and >> on the SilvTask class like this:

int SilvTask::WriteObject(){	A aux(12356, 8956.69f);		testAPointer = FE_NEW A(987, 123.56987f);	// create and open a character archive for output	std::ofstream ofs(m_filename.c_str());	boost::archive::text_oarchive oa(ofs);	        //write class instance to archive	oa << testAPointer;	return FE_OK;}int SilvTask::LoadObject(){	//A newAux;	std::ifstream ifs(m_filename.c_str(), std::ios::binary);	boost::archive::text_iarchive ia(ifs);	//ios::binary ia(ifs);	// read class state from archive	ia >> testAPointer;	return FE_OK;}


I get this compilation errrors:

Quote:

\3rdparty\include\boost\archive\detail\oserializer.hpp(567) : error C2027: use of undefined type 'boost::STATIC_ASSERTION_FAILURE'
with
[
x=false
]
\3rdparty\include\boost\archive\basic_text_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::save(Archive &,T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]
\3rdparty\include\boost\archive\detail\interface_oarchive.hpp(78) : see reference to function template instantiation 'void boost::archive::basic_text_oarchive::save_override(T &,int)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]
\samples\silvestre\main2.cpp(190) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_oarchive::operator <<(T &)' being compiled
with
[
Archive=boost::archive::text_oarchive,
T=FlowEngine::A *
]

gorogoro
gorogoro
Ok!!

The problem was a simple const on the Save function.

Now I'm extended the serialization via derivation.

I've done it sucessfully for the binary archives, but I'm getting a lot of troubles trying to make the same for the text archives.

Have anyone done the same thing?

My link errors are:

Quote:

Creating library ..\..\Bin\silvestre.lib and object ..\..\Bin\silvestre.exp
main2.obj : error LNK2019: unresolved external symbol "public: __thiscall boost::archive::text_oarchive_impl::text_oarchive_impl(class std::basic_ostream > &,unsigned int)" (??0?$text_oarchive_impl@VTextArchiveO@FlowEngine@@@archive@boost@@QAE@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@I@Z) referenced in function "public: __thiscall FlowEngine::TextArchiveO::TextArchiveO(class std::basic_ostream > &,unsigned int)" (??0TextArchiveO@FlowEngine@@QAE@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@I@Z)
main2.obj : error LNK2019: unresolved external symbol "public: __thiscall boost::archive::text_iarchive_impl::text_iarchive_impl(class std::basic_istream > &,unsigned int)" (??0?$text_iarchive_impl@VTextArchiveI@FlowEngine@@@archive@boost@@QAE@AAV?$basic_istream@DU?$char_traits@D@std@@@std@@I@Z) referenced in function "public: __thiscall FlowEngine::TextArchiveI::TextArchiveI(class std::basic_istream > &,unsigned int)" (??0TextArchiveI@FlowEngine@@QAE@AAV?$basic_istream@DU?$char_traits@D@std@@@std@@I@Z)
main2.obj : error LNK2019: unresolved external symbol "public: void __thiscall boost::archive::text_iarchive_impl::load_override(struct boost::archive::class_name_type &,int)" (?load_override@?$text_iarchive_impl@VTextArchiveI@FlowEngine@@@archive@boost@@QAEXAAUclass_name_type@23@H@Z) referenced in function "protected: void __thiscall FlowEngine::TextArchiveI::load_override(struct boost::archive::class_name_type &,int)" (??$load_override@Uclass_name_type@archive@boost@@@TextArchiveI@FlowEngine@@IAEXAAUclass_name_type@archive@boost@@H@Z)
main2.obj : error LNK2019: unresolved external symbol "public: void __thiscall boost::archive::text_oarchive_impl::save(class std::basic_string,class std::allocator > const &)" (?save@?$text_oarchive_impl@VTextArchiveO@FlowEngine@@@archive@boost@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: static void __cdecl boost::archive::save_access::save_primitive,class std::allocator > >(class FlowEngine::TextArchiveO &,class std::basic_string,class std::allocator > const &)" (??$save_primitive@VTextArchiveO@FlowEngine@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@save_access@archive@boost@@SAXAAVTextArchiveO@FlowEngine@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
..\..\Bin\silvestre.exe : fatal error LNK1120: 4 unresolved externals



Thanks

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.