|
Boost Users : |
From: RIVASSEAU Jean Noel (JN.RIVASSEAU_at_[hidden])
Date: 2006-02-27 04:07:32
Hello Robert,
Thanks for your reply. However you did not understand the problem. I read the documentation and understood the purpose of BOOST_EXPORT as explained in the documentation, and as reexplained in your last mail. The problem is at linking, but is not one of undefined reference (template not instantiated), but, on the other hand, *a multiple definition problem.*
If, as suggested, you move BOOST_EXPORT to the class header, even if you move the archive headers before the serialization/export header, you will have multiple instantiations of the same template. This is because every time you include the serialization class header in your program there is some code instantiation, since the EXPORT is in that file. Since this header is included several times in the program, multiple instantiations of the same code occurs (note: apparently this happens even if there is no definition of the templated code to be instantiated (since the implementation is only in the .cc), only a declaration, because BOOST_EXPORT instantiates some kind of *helper code* that gets multiple defined).
Anyway, if you can change the code in order to avoid this multiple definition problem, I'll be glad to test, but I believe it is impossible. However, putting BOOST_EXPORT in the .cc avoids the problem entirely, so this is acceptable.
I am sending again code with your suggested changes, in order to show you your method does not work.
If you look at the code you will see that each serialization header includes <CommonSerialize.h> which contains the archive headers. Then after <CommonSerialize.h> inclusion comes serialization/export.hpp inclusion, so the archive headers are BEFORE export.hpp.
Then follows BOOST_EXPORT. At linking I get the multiple definition problem that I mentioned. If you just move BOOST_EXPORT into the .cc no problems at all.
You can check for yourself if you try to compile the code.
Thank you!!
Jean-Noël
Ps: I ran into two other problems that I'll write mail for later...
OK - BOOST_EXPORT has some non-obvious behavior which I'll explain. Maybe this will help.
BOOST_EXPORT has two functions:
a) To associate a class with an external unique name (GUID)
b) To instanticiate templated code for archives used.
The second is not as obvious as it might seem. Suppose I have:
class A {
};
class B : public A {
}
A * aptr = new B;
text_archive ar;
ar << a;
The problem is that the compiler never sees anything like ar << b so it has no way to know that the
serialization code for B needs to be instantiated for the archive class text_archive.
So each archive class defines a special macro.
Then BOOST_EXPORT instantiates code for each combination of the class and archive class. If this were
not done, one would get a link error with undefined symbol for load<text_archive, B> or something lke that.
Of course the above presumes that the archive classes are included BEFORE the serialization/boost/export.hpp
header.
So if you make the following changes in your code I believe you will get the desired results.
a) Move BOOST_EXPORT to the class header.
b) In test.cc - move the headers boost/archive/... above the headers boost/serialization/..
and let me know that happens.
Robert Ramey
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