[serialization] problem with custom archive type
I have a custom input archive type that has worked fine when statically
linked to the serialization library. I'm now must use serialization as
a DLL and the code no longer compiles. This is under MSVC9 with
BOOST_ALL_DYN_LINK defined. This code works fine on Linux/GCC with
serialization built as a shared library...so the problem appears
specific to Windows/MSVC. Here is a boiled down version of the code
that exhibits the problem:
// HEADER CONTENTS
#include
Kenneth Riddile wrote:
I have a custom input archive type that has worked fine when statically linked to the serialization library. I'm now must use serialization as a DLL and the code no longer compiles. This is under MSVC9 with BOOST_ALL_DYN_LINK defined. This code works fine on Linux/GCC with serialization built as a shared library...so the problem appears specific to Windows/MSVC. Here is a boiled down version of the code that exhibits the problem:
// HEADER CONTENTS #include
class CustomArchive : public boost::archive::xml_iarchive_impl<CustomArchive> , public boost::archive::detail::shared_ptr_helper { public: CustomArchive( std::istream& is, int foo ) : boost::archive::xml_iarchive_impl<CustomArchive>( is, 0 ) , m_foo( foo ) {
}
int GetFoo() const { return m_foo; }
template<class T> void load( T& t ) { boost::archive::xml_iarchive_impl<CustomArchive>::load( t ); }
private: friend class boost::archive::xml_iarchive_impl<CustomArchive>; friend class boost::archive::basic_xml_iarchive<CustomArchive>; friend class boost::archive::load_access;
int m_foo; };
// CPP CONTENTS #include
#include #include #include namespace boost { namespace archive { template class basic_xml_iarchive<CustomArchive>; template class xml_iarchive_impl<CustomArchive>; template class detail::archive_serializer_map<CustomArchive>; } }
BOOST_SERIALIZATION_REGISTER_ARCHIVE( CustomArchive )
and here are the errors:
1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(41) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_start' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(77) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_end' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(83) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(89) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(95) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(101) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(108) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::basic_xml_iarchive' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(111) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::~basic_xml_iarchive' : definition of dllimport function not allowed 1>Warning: This header is deprecated. Please use: boost/spirit/include/classic_rule.hpp 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(83) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(114) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(127) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(140) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(153) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(162) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::init' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(189) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::xml_iarchive_impl' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(202) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::~xml_iarchive_impl'
definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(45) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::insert' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(57) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::erase' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(67) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::find' : definition of dllimport function not allowed
Kenneth Riddile wrote:
I have a custom input archive type that has worked fine when statically linked to the serialization library. I'm now must use serialization as a DLL and the code no longer compiles. This is under MSVC9 with BOOST_ALL_DYN_LINK defined. This code works fine on Linux/GCC with serialization built as a shared library...so the problem appears specific to Windows/MSVC. Here is a boiled down version of the code that exhibits the problem:
The following is labeled "HEADER CONTENTS" but it looks like a *.cpp file to me. I compiled with msvc 7.1 with no problem WHEN I inserted the ...SOURCE line. This line signals that declspec(export) should be used rather than ..import Robert Ramey
// HEADER CONTENTS
#define BOOST_ARCHIVE_SOURCE
#include
class CustomArchive : public boost::archive::xml_iarchive_impl<CustomArchive> , public boost::archive::detail::shared_ptr_helper { public: CustomArchive( std::istream& is, int foo ) : boost::archive::xml_iarchive_impl<CustomArchive>( is, 0 ) , m_foo( foo ) {
}
int GetFoo() const { return m_foo; }
template<class T> void load( T& t ) { boost::archive::xml_iarchive_impl<CustomArchive>::load( t ); }
private: friend class boost::archive::xml_iarchive_impl<CustomArchive>; friend class boost::archive::basic_xml_iarchive<CustomArchive>; friend class boost::archive::load_access;
int m_foo; };
// CPP CONTENTS #include
#include #include #include namespace boost { namespace archive { template class basic_xml_iarchive<CustomArchive>; template class xml_iarchive_impl<CustomArchive>; template class detail::archive_serializer_map<CustomArchive>; } }
BOOST_SERIALIZATION_REGISTER_ARCHIVE( CustomArchive )
and here are the errors:
1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(41) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_start' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(77) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_end' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(83) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(89) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(95) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(101) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(108) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::basic_xml_iarchive' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/basic_xml_iarchive.ipp(111) : error C2491: 'boost::archive::basic_xml_iarchive<Archive>::~basic_xml_iarchive' : definition of dllimport function not allowed 1>Warning: This header is deprecated. Please use: boost/spirit/include/classic_rule.hpp 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(83) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(114) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(127) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(140) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(153) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::load_override' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(162) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::init' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(189) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::xml_iarchive_impl' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/xml_iarchive_impl.ipp(202) : error C2491: 'boost::archive::xml_iarchive_impl<Archive>::~xml_iarchive_impl'
definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(45) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::insert' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(57) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::erase' : definition of dllimport function not allowed 1>C:\Boost\include\boost/archive/impl/archive_serializer_map.ipp(67) : error C2491: 'boost::archive::detail::archive_serializer_map<Archive>::find' : definition of dllimport function not allowed
On 8/25/2010 11:42 PM, Robert Ramey wrote:
#define BOOST_ARCHIVE_SOURCE
Thanks Robert, that got me one step closer. Now, when anything tries to
link with the static library that CustomArchive is a part of, I get a
bunch of unresolved externals like the following (rs::InputArchive ==
CustomArchive):
2>renderer.lib(Material.obj) : error LNK2019: unresolved external symbol
"__declspec(dllimport) protected: __thiscall
boost::archive::xml_iarchive_impl<class
rs::InputArchive>::~xml_iarchive_impl<class rs::InputArchive>(void)"
(__imp_??1?$xml_iarchive_impl@VInputArchive@rs@@@archive@boost@@IAE@XZ)
referenced in function "public: __thiscall
rs::InputArchive::~InputArchive(void)" (??1InputArchive@rs@@QAE@XZ)
2>renderer.lib(Mesh.obj) : error LNK2001: unresolved external symbol
"__declspec(dllimport) protected: __thiscall
boost::archive::xml_iarchive_impl<class
rs::InputArchive>::~xml_iarchive_impl<class rs::InputArchive>(void)"
(__imp_??1?$xml_iarchive_impl@VInputArchive@rs@@@archive@boost@@IAE@XZ)
2>renderer.lib(Model.obj) : error LNK2001: unresolved external symbol
"__declspec(dllimport) protected: __thiscall
boost::archive::xml_iarchive_impl<class
rs::InputArchive>::~xml_iarchive_impl<class rs::InputArchive>(void)"
(__imp_??1?$xml_iarchive_impl@VInputArchive@rs@@@archive@boost@@IAE@XZ)
2>renderer.lib(Material.obj) : error LNK2019: unresolved external symbol
"__declspec(dllimport) protected: __thiscall
boost::archive::xml_iarchive_impl<class
rs::InputArchive>::xml_iarchive_impl<class rs::InputArchive>(class
std::basic_istream
OK - now your in the import/export conumdrum which can be a huge pain in the neck. The basic problem is that given header file x.h is used by code which exports functions and also by code which imports functions. When exporting, the code has to have attributes declspec(export) and when importing it has to have attributes declspec(import). The boost way of handling this was defined by John Maddock. This is described on the boost web site under "advice for libraries built a compile time" (or something like that). It is indispensable that you study this. There is no "cookbook" solution - you have to step back and really thiink about this when you are making your own library type component. So, a) study the documentation described above b) look into the serialization library code to see how the above technique is used c) look a the serialization library tests/examples which refer to makeing DLL compontents. I used a technique similar to the above to make these work. d) now look at your own custom archive and implement these ideas. There is not real coding, it's just setting up a bunch a macros and giving them sensible names and runnig tests. It is tedious but I see no alternative. One option is to use the current archive implementations as model/recipe. I would strongly suggest you consider this. The reason I say this is that to make the same code importable/exportable, there is a bunch of stuff you can't do. Puting some code in static libraries and other code in dynamic libraries is a recipe for excrutiating and endless agony. Think of it as successful marriage, pick your partner and make it work. In my view, the whole DLL thing is the triumph of development over design, it has just grown in response to solving real problems. As far as I know, C/C++ standards say nothing about this. This doesn't help either, etc, etc.... I could go on and on about this, but I don't think it would help anybody much. Robert Ramey Kenneth Riddile wrote:
On 8/25/2010 11:42 PM, Robert Ramey wrote:
#define BOOST_ARCHIVE_SOURCE
Thanks Robert, that got me one step closer. Now, when anything tries to link with the static library that CustomArchive is a part of, I get a bunch of unresolved externals like the following (rs::InputArchive == CustomArchive):
2>renderer.lib(Material.obj) : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall boost::archive::xml_iarchive_impl<class rs::InputArchive>::~xml_iarchive_impl<class rs::InputArchive>(void)"
participants (2)
-
Kenneth Riddile
-
Robert Ramey