Boost logo

Boost Users :

Subject: Re: [Boost-users] [serialization]Multiplydefinedsymbol:guid_initializer
From: Robert Dailey (rcdailey_at_[hidden])
Date: 2009-04-03 16:57:19


On Fri, Apr 3, 2009 at 3:30 PM, Robert Dailey <rcdailey_at_[hidden]> wrote:

> On Fri, Apr 3, 2009 at 4:07 PM, Robert Ramey <ramey_at_[hidden]> 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;



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