Написал свой архиватор для boost::serialization, с целью а) бинарной переносимости б) контроля над форматом пакета
При попытке использовать сериализацию полиморфных классов, выдает ошибки линковки типа
client.o: In function `~pointer_oserializer':
/usr/local/include/boost/archive/detail/oserializer.hpp:222: undefined reference to `boost::archive::detail::archive_serializer_map<raw_binary_oarchive>::erase(boost::archive::detail::basic_serializer const*)'
client.o: In function `void boost::archive::detail::save_pointer_type<raw_binary_oarchive>::polymorphic::save<base>(raw_binary_oarchive&, base&)':
/usr/local/include/boost/archive/detail/oserializer.hpp:435: undefined reference to `boost::archive::detail::archive_serializer_map<raw_binary_oarchive>::find(boost::serialization::extended_type_info const&)'
При попытке определить недостающие функции все линкуется, но падает по sigfault:
namespace boost {
namespace archive {
namespace detail {
template <>
const basic_serializer * archive_serializer_map<raw_binary_oarchive>::find(const boost::serialization::extended_type_info & type_){}
template <>
bool archive_serializer_map<raw_binary_oarchive>::insert(boost::archive::detail::basic_serializer const*){}
template <>
void archive_serializer_map<raw_binary_oarchive>::erase(boost::archive::detail::basic_serializer const*){}
} } }
Вот минимальный код, на котором воспроизводится проблема:
/*
* File: raw_binary_archive.h
*/
#include <boost/archive/binary_oarchive_impl.hpp>
#include <boost/archive/binary_iarchive_impl.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
// include template definitions for base classes used. Otherwise
// you'll get link failure with undefined symbols
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
#include <boost/archive/impl/basic_binary_oarchive.ipp>
#include <boost/archive/impl/basic_binary_iarchive.ipp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/utility/enable_if.hpp>
namespace ba = boost::archive;
class raw_binary_oarchive :
public ba::binary_oarchive_impl<raw_binary_oarchive, std::ostream::char_type,
std::ostream::traits_type> {
typedef raw_binary_oarchive derived_t;
typedef ba::binary_oarchive_impl<raw_binary_oarchive, std::ostream::char_type,
std::ostream::traits_type> base_t;
public:
template<class T>
void save_override(T & t, BOOST_PFTO int) {
base_t::save_override(t, 0);
}
void save_override(const boost::archive::class_name_type & t, int) { }
void save_override(const boost::archive::library_version_type & t, int) { }
void save_override(const boost::archive::version_type & t, int) { }
void save_override(const boost::archive::class_id_type & t, int) { }
void save_override(const boost::archive::class_id_reference_type & t, int) { }
void save_override(const boost::archive::class_id_optional_type & t, int) { }
void save_override(const boost::archive::object_id_type & t, int) { }
void save_override(const boost::archive::object_reference_type & t, int) { }
void save_override(const boost::archive::tracking_type & t, int) { }
public:
raw_binary_oarchive(std::ostream & os, unsigned flags = 0) :
base_t(os, flags | boost::archive::no_header) { }
raw_binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) :
base_t(bsb, flags | boost::archive::no_header) { }
};
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>
#include "raw_binary_archive.h"
struct base {
uint8_t x;
base():x(2){}
virtual ~base(){}
template<class Archive>
inline void serialize(Archive & ar, const unsigned int file_version) {
ar & BOOST_SERIALIZATION_NVP(x);
}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(base)
struct derived_one : public base {
uint8_t y;
derived_one():y(11){}
template<class Archive>
inline void serialize(Archive & ar, const unsigned int file_version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
ar & BOOST_SERIALIZATION_NVP(y);
}
};
BOOST_CLASS_EXPORT(base);
BOOST_CLASS_EXPORT(derived_one);
int main() {
{ boost::archive::detail::archive_serializer_map<raw_binary_oarchive> junk; }
std::ofstream of("test.file");
raw_binary_oarchive archive(of);
archive.register_type<derived_one>();
base* b = new derived_one();
archive << BOOST_SERIALIZATION_NVP(b);
}
Здравствуйте, Аноним, Вы писали:
А>Написал свой архиватор для boost::serialization, с целью а) бинарной переносимости б) контроля над форматом пакета
А>При попытке использовать сериализацию полиморфных классов, выдает ошибки линковки типа
А>А>client.o: In function `~pointer_oserializer':
А>/usr/local/include/boost/archive/detail/oserializer.hpp:222: undefined reference to `boost::archive::detail::archive_serializer_map<raw_binary_oarchive>::erase(boost::archive::detail::basic_serializer const*)'
А>client.o: In function `void boost::archive::detail::save_pointer_type<raw_binary_oarchive>::polymorphic::save<base>(raw_binary_oarchive&, base&)':
А>/usr/local/include/boost/archive/detail/oserializer.hpp:435: undefined reference to `boost::archive::detail::archive_serializer_map<raw_binary_oarchive>::find(boost::serialization::extended_type_info const&)'
Собственно, ошибки повторяются просто при включении хедера архиватора, даже с пустым телом функции main().
Здравствуйте, dcb-BanDos, Вы писали:
DB>Здравствуйте, Аноним, Вы писали:
DB>portable binary archive из examples буста не смотрел?
#include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/impl/archive_serializer_map.ipp>
Буст такой буст