[serialization] binary archiver with generic primitive types

Hi all, The binary_oarchive and binary_iarchive classes serialize an object to a stream whose buffer type is streambuf=basic_streambuf<char>. It means that the serialized object is translated into an array of chars. It is fine if you can work with an array containing chars. Unfortunately, some libraries need serialized objects that are translated into arrays whose type is different from char. For instance, I'm using a library that requires an array of unsigned chars. For that reason, I have defined generic (templated) tbinary_oarchive and tbinary_iarchive classes based on the ones provided by the boost serialization library. It is straightforward since the original boost serialization classes use the std::ostream type that is just an instantiation of the generic basic_ostream class with the char type (ostream=basic_ostream<char>). For instance, the tbinary_oarchive class is now defined as follows: // CODE BEGIN template <class Tdata> class tbinary_oarchive : public binary_oarchive_impl< tbinary_oarchive<Tdata>, typename std::basic_ostream<Tdata>::char_type, typename std::basic_ostream<Tdata>::traits_type > { public: tbinary_oarchive(std::basic_ostream<Tdata> & os, unsigned int flags = 0) : binary_oarchive_impl< tbinary_oarchive, typename std::basic_ostream<Tdata>::char_type, typename std::basic_ostream<Tdata>::traits_type >(os, flags) {} tbinary_oarchive(std::basic_streambuf<Tdata> & bsb, unsigned int flags = 0) : binary_oarchive_impl< tbinary_oarchive, typename std::basic_ostream<Tdata>::char_type, typename std::basic_ostream<Tdata>::traits_type >(bsb, flags) {} }; // CODE END Then, when I need to use a binary archiver with the type unsigned char, I just put the following lines in my code: // CODE BEGIN typedef boost::archive::tbinary_oarchive<unsigned char> BinaryOBArchive; typedef boost::archive::tbinary_iarchive<unsigned char> BinaryIBArchive; BOOST_SERIALIZATION_REGISTER_ARCHIVE(BinaryOBArchive) BOOST_SERIALIZATION_REGISTER_ARCHIVE(BinaryIBArchive) // CODE END This compiles fine except that I get some linker errors concerning the basic_binary_oarchive and the basic_binary_oprimitive classes. For instance: undefined reference to `boost::archive::basic_binary_oprimitive<boost::archive::tbinary_oarchive<unsigned char>, unsigned char, std::char_traits<unsigned char>
::~basic_binary_oprimitive()'
It seems that parts of the serialization library's code is outside the definition classes, preventing to extend it with different binary types... Is there a workaround? Thank you very much for your patience reading this e-mail entirely, Florent.

Florent Teichteil wrote:
This compiles fine except that I get some linker errors concerning the basic_binary_oarchive and the basic_binary_oprimitive classes. For instance: undefined reference to `boost::archive::basic_binary_oprimitive<boost::archive::tbinary_oarchive<unsigned char>, unsigned char, std::char_traits<unsigned char>
:~basic_binary_oprimitive()'
It seems that parts of the serialization library's code is outside the definition classes, preventing to extend it with different binary types... Is there a workaround?
certain code should be explicitly instantitiated. Look at binary_?archive.cpp in libs/serialization/src directory to see how this is done. Robert Ramey

Robert Ramey a écrit :
Florent Teichteil wrote:
This compiles fine except that I get some linker errors concerning the basic_binary_oarchive and the basic_binary_oprimitive classes. For instance: undefined reference to `boost::archive::basic_binary_oprimitive<boost::archive::tbinary_oarchive<unsigned char>, unsigned char, std::char_traits<unsigned char>
:~basic_binary_oprimitive()' It seems that parts of the serialization library's code is outside the definition classes, preventing to extend it with different binary types... Is there a workaround?
certain code should be explicitly instantitiated. Look at binary_?archive.cpp in libs/serialization/src directory to see how this is done.
Thank you for your help. I tried to copy/paste these files into my project and to modify them in order to compile with different primitive types. But new linker errors arise because more source files are required. Besides, copying Boost files in local project source files is dangerous because the copied files have to be updated along with new Boost versions... So I give up, but I would strongly recommend to allow native template archivers with generic primitive types in the Boost serialization library. Thanks again, Florent

On Aug 31, 2009, at 7:48 PM, Florent Teichteil wrote:
Robert Ramey a écrit :
Florent Teichteil wrote:
:~basic_binary_oprimitive()' It seems that parts of the serialization library's code is outside
This compiles fine except that I get some linker errors concerning the basic_binary_oarchive and the basic_binary_oprimitive classes. For instance: undefined reference to ` boost ::archive ::basic_binary_oprimitive<boost::archive::tbinary_oarchive<unsigned char>, unsigned char, std::char_traits<unsigned char> the definition classes, preventing to extend it with different binary types... Is there a workaround? certain code should be explicitly instantitiated. Look at binary_?archive.cpp in libs/serialization/src directory to see how this is done.
Thank you for your help. I tried to copy/paste these files into my project and to modify them in order to compile with different primitive types. But new linker errors arise because more source files are required. Besides, copying Boost files in local project source files is dangerous because the copied files have to be updated along with new Boost versions...
So I give up, but I would strongly recommend to allow native template archivers with generic primitive types in the Boost serialization library.
There is no need to copy these files. You just need to instantiate the templates. Please look at libs/serialization/src /binary_[io]archive.cpp Matthias

Am Monday 31 August 2009 15:34:07 schrieb Florent Teichteil:
undefined reference to `boost::archive::basic_binary_oprimitive<boost::archive::tbinary_oarchive<u nsigned char>, unsigned char, std::char_traits<unsigned char>
::~basic_binary_oprimitive()'
looks like a case of not included .ipp files. I filed a bug report for that a short time ago, try to include all the relevant .ipp files you can find in boost/archive/impl and see if that helps.
So I give up, but I would strongly recommend to allow native template archivers with generic primitive types in the Boost serialization library.
there are many cases that require something else than a char streambuf, I e.g. don't use streambufs at all for performance reasons. so I don't think it makes sense to generalize the archive types to support one more rare use case, when it's impossible to support all use cases. beyond what you can already do: write your own archive.
participants (4)
-
Florent Teichteil
-
Matthias Troyer
-
Robert Ramey
-
Stefan Strasser