Boost logo

Boost Users :

Subject: [Boost-users] [Serialization] Unregistered_class exception
From: elizabeta petreska (elizabeta.petreska_at_[hidden])
Date: 2009-12-23 11:10:02


Hello
And I am sorry for bothering again
The last couple of weeks I am trying to implement saving projects future in
my program with boost serialization.
However it seems that it is more hard that I think :)
Now I am getting unregistered_class exception all over the place

First some info about what I am trying to do :

I am developing a plugin dll , which is loaded in third party main program.
My plugin , say MyPlugin.dll , contains serialization code ( non intrusive
save/load pair ) for classes which are defined in third party dll , say
A.dll. A.dll is suppiled with my third party main program. Both A.dll and
MyPlugin.dll are laoded at runtime in my main program.
Only MyPlugin.dll ( and not A.dll and main program ) links with boost 1.41.0
staticly, if this is relevant at all. And I am using Visual Studio 2005.

I think that I am getting this unregistered_class exception because somehow
I am getting weird behavior from typeid operator ( maybe some bug), for
particular class form A.dll.
Note that the class have virtual methods. That is if I say :

std::string s1=typeid(ON_Brep).raw_name();

ON_Brep someBrepObj;
std:string s2=typeid(someTypeObj).raw_name();

s1 and s2 are not the same string.

I am doing the following :

/////////////////////MyPlugin.cpp
//all archive classes are included here
namespace boost
{
    namespace serialization
    {
        template<class Archive>
        inline void save(Archive & ar,const ON_Brep& t,const unsigned int
version)
        {
          boost::serialization::void_cast_register<ON_Brep, ON_Geometry>(
        static_cast<ON_Brep*>(NULL),
        static_cast<ON_Geometry *>(NULL));
        //save ON_Brep here
        }

        template<class Archive>
        inline void load(Archive & ar,ON_Brep& t,const unsigned int version)
        {
         boost::serialization::void_cast_register<ON_Brep, ON_Geometry>(
        static_cast<ON_Brep*>(NULL),
        static_cast<ON_Geometry *>(NULL));
        //load ON_Brep here
        }
    }
}
BOOST_SERIALIZATION_SPLIT_FREE(ON_Brep)
BOOST_CLASS_EXPORT_GUID(ON_Brep, "ON_Brep")

void CommandFunction()
{
        ON_Brep* brep=GetBrepObject();
        boost::archive::xml_oarchive oa(ofs);
        oa & BOOST_SERIALIZATION_NVP(brep); // fails to save with
uregistered_class exception
}

The unregistered_exception is thrown before control gets to my nonintrusive
save function for my ON_Brep
Actually the exception is thrown in oserializer.hpp in line 376 :

const boost::serialization::extended_type_info * true_type =
                i.get_derived_extended_type_info(t);

// here throws
if(NULL == true_type){
                boost::serialization::throw_exception(
                    archive_exception(
                        archive_exception::unregistered_class,
                        true_type->get_debug_info()
                    )
                );
            }

get_derived_extended_type_info is trying to get the eti record for ON_Brep,
but I think that that it gets it wrong, because of the weird typeid
behavior.

get_derived_extended_type_info(const T & t) const {
        // note: this implementation - based on usage of typeid (rtti)
        // only does something if the class has at least one virtual
function.
        BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value);
        return

typeid_system::extended_type_info_typeid_0::get_extended_type_info(
                typeid(t) ); /////// Here the typeid(t) differs from
typeid(ON_Brep) <------------------1
    }

The thing is when I export ON_Brep with
BOOST_CLASS_EXPORT_GUID(ON_Brep,"ON_Brep") extended_type_info entry is
inserted in the global map, just typeid(ON_Brep) is inserted in the global
map

But when control gets to <-----1 the typeid(t) is different than the typeid
that is entered in the global map,and just looking in the global map fails,
becuase I have different behavior when I apply

typeid(ON_Brep).raw_name();//this gives me ".?AVON_Brep@@"

ON_Brep someBrepObj;
typeid(someBrepObj).raw_name();// this gives me ".?.?AVTL_Brep@@"

Anyone have seen such a thing ?

Thanks for any help



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