[Serialization] 1.33 RC1 Problem linking void_cast_register

My application that works with 1.32 is failing to link with 1.33 RC1 due to boost::serialization::void_cast_register (specialised for my classes) being an unresolved external. In my case the void_cast_register call and the BOOST_CLASS_EXPORT macro are in one module while the serialization is done in another module, with all modules linked in one application. The code below also shows this problem, however if I add an archive class and header to the example then it will compile and link ok. Obviously this is when serialization is in the same module as the void_cast_register call. Any suggestions about what I need to add to make the application link? Richard ************************************************************************ ******* #pragma hdrstop #include <boost/serialization/is_abstract.hpp> #include <boost/serialization/serialization.hpp> #include <boost/serialization/export.hpp> #pragma link "libboost_serialization-bcb-mt-d-1_33.lib" class Z { public: virtual void DoSomething() =0; }; BOOST_IS_ABSTRACT(Z) class A : public Z { public: void DoSomething(){}; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned intversion) { ar & boost::serialization::make_nvp("A", m_A); } int m_A; }; class B : public Z { public: void DoSomething(){}; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned intversion) { ar & boost::serialization::make_nvp("B", m_B); } int m_B; }; BOOST_CLASS_EXPORT(A) BOOST_CLASS_EXPORT(B) int main(int argc, char* argv[]) { boost::serialization::void_cast_register<A, Z>(0,0); boost::serialization::void_cast_register<B, Z>(0,0); return 0; } Errors: [Linker Error] Unresolved external 'const boost::serialization::void_cast_detail::void_caster& boost::serialization::void_cast_register<A, Z>(const A *, const Z *)' referenced from D:\PROJECTS\...\SOURCE\TEST\BUILD\MAIN.OBJ [Linker Error] Unresolved external 'const boost::serialization::void_cast_detail::void_caster& boost::serialization::void_cast_register<B, Z>(const B *, const Z *)' referenced from D:\PROJECTS\...\SOURCE\TEST\BUILD\MAIN.OBJ

"Richard Jennings" <Richard.Jennings@teraview.com> wrote in message news:1CFE360F7FED6D46A110BEF31F2F54FE02A078@JUPITER.Teraview.local...
My application that works with 1.32 is failing to link with 1.33 RC1 due to boost::serialization::void_cast_register (specialised for my classes) being an unresolved external.
In my case these errors were all a result of the new rule that 'serialization' header includes may only appear _after_ 'archive' headers.(which looks to be the case in the code provided) Moving the serialization includes into the translation unit where the archive/serialization code is actually instantiated cleared these errors. This did bring up an issue of needing to forward declare boost::serialization::access. If this header ordering limitation/requirement is here to stay, some sort of forwarding header should probably be provided. Jeff Flinn

I believe this is a side effect of our efforts to be sure that the mere inclusion of a class that includes serialization headers doesn't trigger (through auto-linking) the requirement for inlcuding a library module. The idea is that one would never need "void_cast_register<T>" to be generated unless there is an archive somewhere involved. So that raises the question of what the context is here. Your test illustrates the link error but it doesn't illustrate the use case. That is, what is the context of explicitly invoking void_cast_register without an archive header present? I'm not saying its wrong. Its just that I don't see how this comes up. When we implemented changes which resulted in this symptom - we enivisioned a pattern of usage like that shown below. In this way, the *.hpp files could be included in other programs without triggering auto-link and requiring linking with the boost library to include code that in fact will never be used. Were we missing something here? What is it? Robert Ramey Z.hpp ==== #include <boost/serialization/is_abstract.hpp> #include <boost/serialization/serialization.hpp> #include <boost/serialization/export.hpp> class Z ... }; BOOST_IS_ABSTRACT(Z) A.hpp ==== #include ... // other serialization headers #include "Z.hpp" class A : public Z { A(){ boost::serialization::void_cast_register<A, Z>(0,0); } }; BOOST_CLASS_EXPORT(A) B.hpp ==== #include ... // other serialization headers #include "Z.hpp" class B : public Z { ... B(){ boost::serialization::void_cast_register<B, Z>(0,0); } }; BOOST_CLASS_EXPORT(B) main.cpp ====== #include <boost/serialization/text_oarchive.hpp> #include <boost/serialization/text_iarchive.hpp> #include "Z.hpp" #include "A.hpp" #include "B.hpp" int main(int argc, char* argv[]){ return 0; }

After posting the above, I realize that my pattern/solution wasn't quite complete
B(){ boost::serialization::void_cast_register<B, Z>(0,0); }
should be B(); with a corresponding B(){ boost::serialization::void_cast_register<B, Z>(0,0); } In a module like B.hpp. As you can see, there are a couple of loose ends here. Its not all clear to me what - if anything - should be done here. Robert Ramey
participants (3)
-
Jeff Flinn
-
Richard Jennings
-
Robert Ramey