|
Boost Users : |
From: Reusser, Edward (Edward.Reusser_at_[hidden])
Date: 2006-11-13 15:48:06
Robert,
Thanks for the quick response. I have ensured that the serialization
for each type is located in exactly one place. The header files where
the serialization code resides for the derived classes are not global,
that is, our build system is set up to ensure that no other library or
DLL can reference them.
I believe that I can make the serialization completely independent and
contained inside the DLL without much difficulty. However, unless I
statically link the serialization library, I don't think I can prevent
the macro:
BOOST_CLASS_EXPORT_GUID( class, "ClassNameText" )
from initializing the global table inside the serialization DLL (which
is dynamically linked). I noticed that when I tried to use the other
registration technique you describe, register_type<T>(), this also calls
the registration code in the serialization DLL on load, so that doesn't
solve the problem.
It doesn't seem very practical to serializing in/out a prototype of each
derived class into the archive initially because it would increase the
archive size by a lot.
Too bad there isn't a mechanism for creating a registration table
specific to the DLL where the classes are serialized. If the global
table was of the following structure:
using namespace std;
map< HMODULE, map<string, ETI*> >;
Then the above macro would simply use AfxGetInstanceHandle (in the case
of windows, I am unsure what the corresponding calls in other OS's would
be), to pass the HMODULE handle.
Ed
-----Original Message-----
From: Robert Ramey [mailto:ramey_at_[hidden]]
Sent: Monday, November 13, 2006 8:24 AM
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] [Serialization] unexpected assert
registeringclasses
Having serialization code in DLLS has raised some stick issues. The
basic
problem is the existence of a global table of information about types
being
serialized. Among other thngs, this global type table contains the
export
string name (GUID) that is shared among programs to identify the type.
This
table also points to functions via a virtual function mechnamism to
implementations required by serialization.
Entries are added to this table when code is loaded and deleted when
code is
unloaded.
in version 1.33 I included the indicated assert - as it seemed to me
that
this must be unique. I was concerned that multiple entries in the table
might point to different function implementations - as
indeed they will. So I included this assertion.
This started to create problems as you have found. Also I've now come
to
thnk that the
having multiple entries for the same type is harmless - and difficult to
avoid in the
presence of dynamically loaded/unloaded DLLS. So in 1.34 - I commmented
out
the assertion.
In addition, I've augmented the code to make sure that the correct entry
in
the table is
deleted when the corresponding DLL is unloaded. So I believe that
starting
in 1.34 this
problem will be resolved. I really don't know for sure because its very
hard to come up
with a good test for this.
So, I think this problem is addressed. But in the face of dynamically
loaded
DLLs - which are not
all guarenteed to be in sync ( some could have older versions of code),
I
think that the best
policy would be to be sure that serialzation code for a particular type
should be found in one
and only one place. Also, doing this will result in smaller DLLS and
applications. Doing this
requires that one explicitly orgranize his code so to achieve this.
This
means avoiding instantiation
of serialization code in applications and by explicitly instantiation
such
code in the DLLS. The
closest guide I have for doing this is demo_pimpl which shows how to do
this.
Robert Ramey
"Reusser, Edward" <Edward.Reusser_at_[hidden]> wrote in message
news:5E916BAE1732F344BAFD713DF2373479016EA054_at_SV-MSG-01.amer.actel.com..
.
I am using the boost 1.33.1 distribution, and the xml_iarchive and
xml_oachive to serialize a rather deep and complex data structure to
xml. I
am using make_nvp directly in all cases (not the macro).
I am sometimes getting the following assert (line 71 in
extended_type_info.cpp) when I load previously serialized data:
assert( lookup(eti) == m_self->m_map.end() );
It seems obvious that what is happening is that somehow I am calling
self_register more than once for a specific class. Tracing through the
code
however I am puzzled exactly how this could happen, since the
registration
should only happen once when the libraries are loaded. This never
happens
on save by the way, only on load. It also never happens if I do the
save,
followed by a load immediately. It only happens if I do the save, shut
down
the application, then load the data. I have verified that the loaded
data
is a bit by bit equivalent in both cases.
The best that I can come up with is that I am loading the serialization
library as a side effect of calling LoadLibrary at runtime. So I am
linking
in the serialization library after everything else has been loaded and
is
running. But again, none of the libraries are ever unloaded, and the
load
sequence should always be the same.
The actual situation is that I have a library . call it Library A, which
is
linked to libraries B, and C. The library A is being linked using the
LoadLibrary call, each of libraries B are C are linked to the boost
serialization library.
In each of libraries B, and C, I have used the macro:
BOOST_CLASS_EXPORT_GUID( class, "ClassNameText" )
To define all of my classes I am serializing, including all classes that
I
am serializing using shared_ptr's. I was thinking originally that the
problems were all shared_ptr's of classes that are derived from
enable_shared_from_this<T>, but I am no longer confident that has
anything
to do with it.
In fact, truth be told, I have no idea if any of the above has anything
to
do with the problem. When I commented out the assertion, everything
seems
to work just fine, except now I am getting a stack overflow on very
complex
hierarchies in the spirit parser (again, load only), but the simpler
ones
seem to work repeatedly without any problems.
I have no doubt that the assertion was added there for a reason, so I
hate
to comment it out without finding out what else I might have broken.
Edward Reusser
Principal Engineer
Actel Corporation
(650) 318-4972
The information contained in or attached to this email may be subject to
the
Export Administration Regulations (EAR), administered by the U.S.
Department
of Commerce, or the International Traffic in Arms Regulations (ITAR),
administered by the U.S. Department of State, and may require an export
license from the Commerce or State Department prior to its export. An
export
can include a release or disclosure to a foreign national inside or
outside
the United States. Include this notice with any reproduced portion of
this
information.
_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
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