BOOST_CLASS_EXPORT_ *宏无法像register_type()一样工作 [英] BOOST_CLASS_EXPORT_* macros are not working like register_type()
问题描述
当我将派生对象序列化到文件中,并在使用boost导出宏时从该文件序列化到基类指针时,出现unregistered_class异常.当我用存档的register_type()方法替换宏时,它可以工作.我需要使用宏,因为应用程序的大小和复杂性使register_type()方法不切实际.
I am getting an unregistered_class exception when I serialize out a derived object to a file and serialize in from that file to a base class pointer when I use the boost export macros. When I replace the macros with the archive register_type() methods, it works. I need to use the macros because the application size and complexity makes the register_type() methods impractical.
我正在使用RHEL 7.4,boost 1.53和C ++ 11.这些类在共享库中.这里是示例代码来演示此问题.照原样,它引发异常.如果我注释掉宏并取消注释功能,它将起作用.testera.h
I am using RHEL 7.4, boost 1.53, and C++11. The classes are in shared libraries. Here is sample code to demonstrate the problem. As is, it throws the exception. If I comment out the macros and uncomment the functions, it works. testera.h
#ifndef testera_h
#define testera_h
#include <boost/serialization/serialization.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/string.hpp>
class A
{
private:
friend class boost::serialization::access;
template< class Arch >
void
serialize( Arch &ar, const unsigned int ver );
public:
A();
virtual ~A() {}
void setStr( const std::string &s );
std::string getStr();
protected:
std::string myStr;
};
BOOST_CLASS_EXPORT_KEY(A)
#endif
testera.C
testera.C
#include "testera.h"
BOOST_CLASS_EXPORT_IMPLEMENT(A)
template
void
A::serialize<boost::archive::polymorphic_oarchive>( boost:archive::polymorphic_oarchive &ar, const unsigned int ver );
template
void
A::serialize<boost::archive::polymorphic_iarchive>( boost::archive::polymorphic_iarchive &ar, const unsigned int ver );
A::A() : myStr( "a" )
{
}
void
A::setStr( const std::string &s )
{
myStr = s;
}
std::string
A::getStr()
{
return myStr;
}
template<class Arch>
void
A::serialize( Arch &ar, const unsigned int ver )
{
ar & myStr;
}
testerb.h
testerb.h
#ifndef testerb_h
#define testerb_h
#include "testera.h"
class B : public A
{
private:
friend class boost::serialization::access;
template< class Arch >
void
serialize( Arch &ar, const unsigned int ver );
public:
B();
virtual ~B() {}
void set( const int i );
int get();
protected:
int myI;
};
BOOST_CLASS_EXPORT_KEY(B)
#endif
testerb.C
testerb.C
#include "testerb.h"
BOOST_CLASS_EXPORT_IMPLEMENT(B)
template
void
B::serialize<boost::archive::polymorphic_oarchive>( boost::archive::polymorphic_oarchive &ar, const unsigned int ver );
template
void
B::serialize<boost::archive::polymorphic_iarchive>( boost::archive::polymorphic_iarchive &ar, const unsigned int ver );
B::B(): myI( 1 )
{
myStr = "b";
}
void
B::set( const int i )
{
myI = i;
}
int
B::get()
{
return myI;
}
template< class Arch >
void
B::serialize( Arch &ar, const unsigned int ver )
{
// boost::serialization::void_cast_register< B, A >( static_cast< B *>( NULL ), static_cast< A * >( NULL ) );
ar & boost::serialization::base_object<A>( *this );
ar & myI;
}
tester_mn.C
tester_mn.C
#include "testerb.h"
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <fstream>
int main( int argc, char *argv[] )
{
int ret = 0;
B obj;
obj.set( 2 );
A *ptr = NULL;
if( argc > 1 )
{
try
{
std::string fl = argv[ 1 ];
{
std::ofstream ofl( fl.c_str() );
/*
oar->register_type(static_cast<A *>(NULL));
oar->register_type(static_cast<B *>(NULL));
*/
try
{
boost::archive::polymorphic_text_oarchive toar( ofl );
toar & obj;
}
catch( std::exception &e )
{
std::cerr << "Error: archive from B to file " << fl << " - " << e.what() << std::endl;
ret = 1;
}
}
if( ! ret )
{
ptr = NULL;
{
std::ifstream ifl( fl.c_str() );
/*
iar->register_type(static_cast<A *>(NULL));
iar->register_type(static_cast<B *>(NULL));
*/
try
{
boost::archive::polymorphic_text_iarchive tiar( ifl );
tiar & ptr;
}
catch( std::exception &e )
{
std::cerr << "Error: archive from file " << fl << " to B * - " << e.what() << std::endl;
ret = 1;
}
catch( ... )
{
std::cerr << "Error: Caught excpeption" << std::endl;
ret = 1;
}
}
if( ! ret )
{
std::cout << static_cast<B*>(ptr)->get() << std::endl;
}
}
}
catch( ... )
{
std::cerr << "Caught exception" << std::endl;
ret = 1;
}
}
return ret;
}
Makefile_lib
Makefile_lib
CXXFLAGS = -c -ggdb3 -fPIC -funswitch-loops -fgcse-after-reload -std=c++11
LDFLAGS = -std=c++11 -lboost_serialization -lboost_thread -lboost_system -lboost_filesystem
OBJLOC = obj
OBJS = $(OBJLOC)/testera.o \
$(OBJLOC)/testerb.o
LIBRARY_NAME = libtester.so
libs:$(LIBRARY_NAME)
$(LIBRARY_NAME): $(OBJS)
${CXX} -shared -o $@ $(OBJS)
$(OBJLOC)/%.o: ./%.C
$(CXX) $(CXXFLAGS) ./$*.C -o $(OBJLOC)/$*.o
Makefile_mn
Makefile_mn
CXXFLAGS = -ggdb3 -funswitch-loops -fgcse-after-reload -std=c++11
LDFLAGS = -lboost_serialization -lboost_thread -lboost_system -lboost_filesystem -L. -ltester
tester_mn: tester_mn.o
${CXX} $(CXXFLAGS) $(LDFLAGS) tester_mn.C -o $@
推荐答案
这篇关于BOOST_CLASS_EXPORT_ *宏无法像register_type()一样工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!