[boost::serialization] Serializing Dynamically Loaded Libraries - "Unregistered Void Cast"
I already sent a message on this topic a few weeks ago, however, my problem
has a changed a bit so I decided to post a new message.
I've been trying to get Boost serialization working for dynamically loaded
shared libraries. Here's my basic structure simplified:
1. base.hpp - includes an abstract base class called base
2. derived.hpp - includes a derived class from base. includes base.hpp.
3. derived.cpp - includes code for derived class and for dynamically loading
it
4. main.cpp - includes base.hpp but NOT derived.hpp. dynamically loads
instantiates a base * which points to a derived object from derived.so
Now in main I want to be able to serialize my pointer to the loaded derived
class:
base *obj = create_func(); //obj now points to a derived object
obj->test(); //when test is run it correctly outputs the message from
derived.cpp
const base* const to_serialize = obj;
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
try
{
oa << (to_serialize);
}
catch(exception &e)
{
cout << "Exception: " << e.what() << "\n";
}
It compiles fine and I got past the "unregisterd class" problem, but now
when I try to serialize the pointer an exception is caught:
"Unregistered void cast"
This appears to be a problem with registering the derived pointer type from
the base type when dynamically loaded from a shared library.
However, I do register the derived-base relationship as suggested in the
documentation. The serialize method in derived.hpp is as follows:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar.template register_type(static_cast
((( All -- please ignore my previous post; I have resolved the problem
and didn't intend to send that message )))
Hi Jeshua,
Vaguely related comment on your problem. I was also recently seeing this
"unregistered void cast" runtime error. As far as I could tell it was a
problem relating to my ordering and placement of "#include
I already sent a message on this topic a few weeks ago, however, my problem has a changed a bit so I decided to post a new message.
I've been trying to get Boost serialization working for dynamically loaded shared libraries. Here's my basic structure simplified:
1. base.hpp - includes an abstract base class called base 2. derived.hpp - includes a derived class from base. includes base.hpp. 3. derived.cpp - includes code for derived class and for dynamically loading it 4. main.cpp - includes base.hpp but NOT derived.hpp. dynamically loads instantiates a base * which points to a derived object from derived.so
Now in main I want to be able to serialize my pointer to the loaded derived class:
base *obj = create_func(); //obj now points to a derived object obj->test(); //when test is run it correctly outputs the message from derived.cpp
const base* const to_serialize = obj; std::ofstream ofs("filename"); boost::archive::text_oarchive oa(ofs); try { oa << (to_serialize); } catch(exception &e) { cout << "Exception: " << e.what() << "\n"; }
It compiles fine and I got past the "unregisterd class" problem, but now when I try to serialize the pointer an exception is caught: "Unregistered void cast"
This appears to be a problem with registering the derived pointer type from the base type when dynamically loaded from a shared library.
However, I do register the derived-base relationship as suggested in the documentation. The serialize method in derived.hpp is as follows:
template<class Archive> void serialize(Archive & ar, const unsigned int version) {
ar.template register_type(static_cast
(NULL)); //ar & boost::serialization::base_object<base>(*this); ar & data; boost::serialization::void_cast_register( static_cast (NULL), static_cast (NULL) ); } If anyone knows the cause of this and/or a solution I would be very appreciative. I've been working at this for a long time now and I'm almost ready to write my own simple serialization for my specific purpose.
Thank you for your help, Jeshua Bratman
John Pye-4 wrote:
Hi Jeshua,
Vaguely related comment on your problem. I was also recently seeing this "unregistered void cast" runtime error. As far as I could tell it was a problem relating to my ordering and placement of "#include
(or ditto iarchive), and "#include as well as calls to BOOST_CLASS_EXPORT. It was nothing to do with my use of void_cast_register, which in fact I don't use anywhere in any of my code.
So FWIW I think that this error message is not particularly helpful or well-worded.
Cheers JP
JP,
Thanks for the comment.
This issue was mentioned to me in my previous message I sent out. I believe
I have the includes ordered correctly. What Robert said was that I need to
include the archives before the export header file. Here's the order in
which I include the serialization headers:
#include
I think this is because one half of code that registers classes relationship resides in derived.so and the other part resides in main. The first part is the
BOOST_CLASS_EXPORT_GUID(derived,"derived") - it instantiates pointer_oserializer and pointer_iserializer for known archives and derived (and, in turn,
extended_type_info for derived), the second pairt is in derived serialize function - "ar & boost::serialization::base_object<base>(*this);" - it instantiated in main and calls void_cast_register internally. Try to move BOOST_CLASS_EXPORT_GUID(derived,"derived") into derived.hpp - I guess that it will force instantiation of pointer_oserializer/pointer_iserializer in main.
I had similar problem with MSVC.
Sorry for my poor English
"Jeshua Bratman"
John Pye-4 wrote:
Hi Jeshua,
Vaguely related comment on your problem. I was also recently seeing this "unregistered void cast" runtime error. As far as I could tell it was a problem relating to my ordering and placement of "#include
(or ditto iarchive), and "#include as well as calls to BOOST_CLASS_EXPORT. It was nothing to do with my use of void_cast_register, which in fact I don't use anywhere in any of my code.
So FWIW I think that this error message is not particularly helpful or well-worded.
Cheers JP
JP,
Thanks for the comment.
This issue was mentioned to me in my previous message I sent out. I believe I have the includes ordered correctly. What Robert said was that I need to include the archives before the export header file. Here's the order in which I include the serialization headers:
#include
#include #include #include #include Here is my code just to make things easier. There should be 5 files: Makefile main.cpp base.hpp derived.hpp derived.cpp
http://www.nabble.com/file/p12487645/serialization_dynamic_test.tar.gz serialization_dynamic_test.tar.gz
Thanks, Jeshua Bratman -- View this message in context: http://www.nabble.com/-boost%3A%3Aserialization--Serializing-Dynamically-Loa... Sent from the Boost - Users mailing list archive at Nabble.com.
Sergey Skorniakov wrote:
I think this is because one half of code that registers classes relationship resides in derived.so and the other part resides in main.
Yeah, that is the problem that I'm having to deal with for a dynamically loaded library. Main can't have the code to register derived because it doesn't know the derived class exists. Try to move BOOST_CLASS_EXPORT_GUID(derived,"derived") into derived.hpp - I guess that it will force instantiation of pointer_oserializer/pointer_iserializer in main.
I tried putting all the serialization code into the header file but I still get the exact same runtime error. I don't think this should matter though unless I am including the header file for derived somewhere else.
Sorry for my poor English
You're English is fine. Besides I'm happy to get any help I can get! -- View this message in context: http://www.nabble.com/-boost%3A%3Aserialization--Serializing-Dynamically-Loa... Sent from the Boost - Users mailing list archive at Nabble.com.
I tried putting all the serialization code into the header file but I still get the exact same runtime error. I don't think this should matter though unless I am including the header file for derived somewhere else.
My mistake - I didn't noticed that you don't include derived.hpp in main. I am not familiar with gcc and *nux, but you should check that main and derived are linked to .so version of serialization library. Its necessary that all parts of programs use single instance of typeinfo registry (tkmap and ktmap from serialization/src/extended_type_info.cpp, and void_caster_registry from serialization/src/void_cast.cpp). Unfortunatelly, its not enough. On MS Windows, there are at two other issues related to dynamically loadable libraries - multiple registration of type in tkmap (it is indicated by assert) and problem with different tracking level of the same type in different executable modules. I'm not tested these problems on Linux, but guess that it should be similar.
Hello This topic is also discussed in the web documentation: http://www.boost.org/libs/serialization/doc/special.html#export I am currently struggling with the same issue! cheers Robbie --- Robbie Morrison PhD student -- policy-oriented energy system simulation Institute for Energy Engineering (IET) Technical University of Berlin (TU-Berlin), Germany [from IMAP client] Jeshua Bratman wrote:
John Pye-4 wrote:
Hi Jeshua,
Vaguely related comment on your problem. I was also recently seeing this "unregistered void cast" runtime error. As far as I could tell it was a problem relating to my ordering and placement of "#include
(or ditto iarchive), and "#include as well as calls to BOOST_CLASS_EXPORT. It was nothing to do with my use of void_cast_register, which in fact I don't use anywhere in any of my code.
So FWIW I think that this error message is not particularly helpful or well-worded.
Cheers JP
JP,
Thanks for the comment.
This issue was mentioned to me in my previous message I sent out. I believe I have the includes ordered correctly. What Robert said was that I need to include the archives before the export header file. Here's the order in which I include the serialization headers:
#include
#include #include #include #include Here is my code just to make things easier. There should be 5 files:
[snip: list of files]
Thanks, Jeshua Bratman
-- View this message in context: http://www.nabble.com/-boost%3A%3Aserialization--Serializing-Dynamically-Loa... Sent from the Boost - Users mailing list archive at Nabble.com.
Robbie Morrison wrote:
This topic is also discussed in the web documentation:
http://www.boost.org/libs/serialization/doc/special.html#export
I am currently struggling with the same issue!
Yeah, I've already seen that documentation. So you're trying to get serialization working on a dynamically loaded shared library as well? Jeshua -- View this message in context: http://www.nabble.com/-boost%3A%3Aserialization--Serializing-Dynamically-Loa... Sent from the Boost - Users mailing list archive at Nabble.com.
participants (4)
-
Jeshua Bratman
-
John Pye
-
Robbie Morrison
-
Sergey Skorniakov