[serialization] unregistered class exception during serialization from DLL
Hello All,
I have some classes needed to be serialized (A.HPP und A.CPP below).
The serialization happens over the pointer to the base class. The code is
called in
the function (FUNC.CPP below).
The files A.HPP, A.CPP and FUNC.CPP are constituents of a bigger
DLL-library.
If my test application is linked dynamical against the DLL-libary then the
code throws an exception
"unregistered class - derived class not registered or exported".
What is wrong in my code? The code is compiled with Visual Studio 2012
(default settings).
Boost: 1.53.0
If I look into
BOOST_SERIALIZATION_DECL(const extended_type_info *)
extended_type_info_typeid_0::get_extended_type_info(
const std::type_info & ti
) const {
typeid_system::extended_type_info_typeid_arg etia(ti);
const tkmap & t = singleton<tkmap>::get_const_instance();
const tkmap::const_iterator it = t.find(& etia);
if(t.end() == it)
return NULL;
return *(it);
}
then I see that Ord<Options> is not registered in
singleton<tkmap>::get_const_instance().
Moreover, I am not able to set breakpoint into Ord<Options>::serialize().
According to MSVC debugger the breakpoint will not be hit.
Additional remarks:
1) If I uncomment the code lines in FUNC.CPP then everything works.
2) If I link the code statical to my test application then everything is
also fine.
-----------------------A.HPP-----------------------------------------------
#include "archive.hpp" // includes the required headers
struct OrdBasis {
virtual ~OrdBasis() {}
virtual bool is_base_of(const boost::shared_ptr<OrdBasis>& derived_ptr)
{ return true; }
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
}
};
template<typename P> struct Ord;
struct Options
{
Options() {}
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
}
};
template<> class Ord<Options> : public OrdBasis
{
typedef Ord<Options> P;
bool is_base_of(const boost::shared_ptr<OrdBasis>& derived_ptr)
{
const boost::shared_ptr<P> base_ptr =
boost::dynamic_pointer_cast<P>(derived_ptr);
bool result = (base_ptr) ? true : false;
return result;
}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(OrdBasis);
}
};
BOOST_CLASS_EXPORT_KEY(Ord<Options>)
-----------------------A.HPP-------------------------------------------
-----------------------A.CPP-------------------------------------------
#include "A.hpp"
BOOST_CLASS_EXPORT_IMPLEMENT(Ord<Options>)
-----------------------A.CPP-------------------------------------------
I serialize with following sequence
---------------------FUNC.CPP------------------------------------------
void serializeFunc()
{
namespace io = boost::iostreams;
typedef std::vector<char> buffer_type;
buffer_type buffer;
buffer.reserve(2000000);
{
buffer.clear();
io::stream
Hello All, I have investigated the issue little bit more. I have observed the following: The code works properly after shifting of ~OrdBasis() definition into the source code. Hence, I suppose that compiler suite of MVSC 11.0 ignores in fact the results of A.CPP file. The result is obvious. Registration by BOOST_CLASS_EXPORT_IMPLEMENT(Ord<Options>) is not done. The same behavior was reproduced with MSVC 10.0 (Visual Studio 2010). Curiously, the situation depends on the code that is shifted to the source code file. The shifting of the Option class constructor in to the source code is not sufficient. Could anyone, please, check the behavior with other compilers. Is it a compiler suite (linker or compiler) bug? Or the problem with boost implementation? Kind Regards,
Andreas Mainik wrote:
Hello All,
I have investigated the issue little bit more. I have observed the following:
The code works properly after shifting of ~OrdBasis() definition into the source code. Hence, I suppose that compiler suite of MVSC 11.0 ignores in fact the results of A.CPP file. The result is obvious. Registration by BOOST_CLASS_EXPORT_IMPLEMENT(Ord<Options>) is not done.
The same behavior was reproduced with MSVC 10.0 (Visual Studio 2010).
Curiously, the situation depends on the code that is shifted to the source code file. The shifting of the Option class constructor in to the source code is not sufficient.
Could anyone, please, check the behavior with other compilers.
Is it a compiler suite (linker or compiler) bug? Or the problem with boost implementation?
Kind Regards,
Andreas Mainik wrote:
Hello All,
I have investigated the issue little bit more. I have observed the following:
The code works properly after shifting of ~OrdBasis() definition into the source code. Hence, I suppose that compiler suite of MVSC 11.0 ignores in fact the results of A.CPP file. The result is obvious. Registration by BOOST_CLASS_EXPORT_IMPLEMENT(Ord<Options>) is not done.
The same behavior was reproduced with MSVC 10.0 (Visual Studio 2010).
Curiously, the situation depends on the code that is shifted to the source code file. The shifting of the Option class constructor in to the source code is not sufficient.
Could anyone, please, check the behavior with other compilers.
Is it a compiler suite (linker or compiler) bug? Or the problem with boost implementation?
The problem is that compilers attempt to eliminate code that doesn't seem to be necessary. The inline version just get's elimnated and the compiler/linker figures there's nothing left to do and won't even hook the DLL. If you use the out of line code, it figures that you need to include the DLL which in turn starts the whole chain of instantiation. This is not some much a question of the serialization library as a question about how to deal with generated code in a DLL. C++ currently has left undefined what should be done in cases like this. The usage of DLLS trips a number of issues which are currently undefined by the C++ standard - which barely touches on issues of linking in any case. Take a look at the examples in the package labeled "Polymorphic" for some hints to get more predictable behavior in these cases. Robert Ramey
participants (2)
-
Andreas Mainik
-
Robert Ramey