On Fri, Apr 3, 2009 at 3:30 PM, Robert Dailey <rcdailey@gmail.com> wrote:
On Fri, Apr 3, 2009 at 4:07 PM, Robert Ramey <ramey@rrsd.com> wrote:
**** at this point, the serialization library doesn't necessary doesn't know anything about derived. (I'm assuming derived is polymorphic.)  Depending on what is compiled into the library and waht is inline, there may or may not be a problem at link time

Sorry I feel like we're going in circles about this. Let me explain in detail how I see what is happening.

Because I'm calling functions off of "base" polymophically from my executable using the LIB in question, it *cannot* ignore the two classes "base" and "derived", because I'm actually using the code. The polymorphic behavior of the function call "base->DoStuff()" touches the implementations of that function in "base::DoStuff()" and "derived::DoStuff()".

So it isn't the classes themselves being ignored, it has to be something else. When I call "BOOST_CLASS_EXPORT( derived )", it creates a specialization of the class "init_guid<>". Right below that, the static variable inside the "init_guid" struct is statically initialized with some value from a singleton. This class *cannot* be going away, because the act of calling a member function off of "derived" (e.g. derived::DoStuff() ) causes that translation unit to be visited, thus causing that static member to be initialized.

So it seems that given the circumstances, nothing in this translation unit is going away. Because I am calling a member function off of my "derived" instance before I serialize it out, the translation unit is being "visited" and that alone is all that the "derived" class needs.

However, the "base" class has no implementation for "DoStuff", it is pure virtual. This means the "base" translation unit is not being visited. Is this the problem? This might be the reason for the "unregistered void cast" error. Am I on the right track about all of this?

You mentioned a "force_export" header of some sort, but I'm not sure where you are going with this. As far as I know, this is undocumented behavior in Boost.Serialization. If someone wouldn't mind providing me a detailed and functional example of how to use this "force_export" concept, I would appreciate it. I also do not wish to use archive.register_type<>, because this requires doing this for every archive I am using. If I add a new derived type, I'll have to go back and change this. This violates the open/close principle.

This whole thing is pretty confusing, so I hope you'll bear with me while I try to understand this.

In our current example we've been using 2 classes: "base" and "derived". These are not accurate examples, however. In reality the "base" class is actually "Widget", and "derived" is "StaticText". Widget has:

Widget::SetPosition()

This function is implemented in Widget.cpp. Widget.cpp also has the BOOST_CLASS_EXPORT( Widget ) call.

StaticText has a constructor that takes a string, which is also implemented in StaticText.cpp. This file also has BOOST_CLASS_EXPORT( StaticText )

So when I have code in my executable that does this:

StaticText* text = new rs::StaticText( "Hello World" );
text->SetPosition( 20, 20 );

The first line of code results in the constructor for staticText to be called, which means StaticText.cpp gets "touched". The second line calls the non-virtual SetPosition() call  in base class Widget, which results in Widget.cpp getting touched.

So both translation units are getting touched, which means both macros are being executed. This should work just fine, right? Later on I do this:

Widget* widget = text;
archive << widget;