Boost logo

Boost Users :

Subject: [Boost-users] [serialization] unregistered class exception during serialization from DLL
From: Andreas Mainik (amainik_at_[hidden])
Date: 2013-07-13 09:59:54


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<io::back_insert_device<buffer_type> >
    output_stream(buffer);
    boost::archive::binary_oarchive oa(output_stream,
     boost::archive::no_header);

    // begin
    //if the following lines are commented out then everything works
    //boost::shared_ptr<Ord<Options>> testOptOrd(new Ord<Options>);
    //oa & testOptOrd;
    //end

    boost::shared_ptr<OrdBasis> testOptOrdB(new Ord<Options>);
    oa & testOptOrdB;
  }
        
  {
   io::basic_array_source<char> source(&buffer[0],buffer.size());
   io::stream<io::basic_array_source <char> > input_stream(source);
   boost::archive::binary_iarchive ia(input_stream,
    boost::archive::no_header);
   boost::shared_ptr<OrdBasis> testOptOrd;

   // begin linked to the above code block
   //ia & testOptOrd;
   // end
   ia & testOptOrd;
   int i = 0;
  }
}
-----------------------FUNC.CPP------------------------------------

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net