-
Notifications
You must be signed in to change notification settings - Fork 807
Description
Today it is not possible to use cereal when serialization classes exist in different windows dll files.
The problem seems to be that each dll files get their own instance of the cereal::detail::StaticObject.
I think that to fix this it must be possible to set the dllexport/dllimport storage-class attributes on the cereal::detail::StaticObject to make sure access is done only through one dll file. And it must also be possible to instantiate the cereal::detail::StaticObject in a cpp file.
Example
base.h
#pragma once
#include < memory >
#include < cereal/cereal.hpp >
#include < cereal/archives/binary.hpp >
#include < cereal/types/polymorphic.hpp >
#if defined (_WINDLL)
#define DECLSPECIFIER __declspec(dllexport)
#else
#define DECLSPECIFIER __declspec(dllimport)
#endif
class Base /*abstract*/
{
public:
friend class cereal::access;
template < class Archive >
DECLSPECIFIER void serialize(Archive & ar, std::uint32_t const version);
virtual ~Base() {}
};
extern template DECLSPECIFIER void Base::serialize<cereal::BinaryOutputArchive>
( cereal::BinaryOutputArchive & ar, std::uint32_t const version );
base.cpp
#include "Base.h"
CEREAL_REGISTER_TYPE(Base)
template void Base::serialize<cereal::BinaryOutputArchive>
( cereal::BinaryOutputArchive & ar, std::uint32_t const version );
template <class Archive>
void Base::serialize(Archive & ar, std::uint32_t const version)
{
}
derived.h
#pragma once
#include "Base.h"
class Derived : public Base
{
private:
friend class cereal::access;
template <class Archive>
void serialize(Archive & ar, std::uint32_t const version);
};
extern template DECLSPECIFIER void Derived::serialize<cereal::BinaryOutputArchive>
( cereal::BinaryOutputArchive & ar, std::uint32_t const version );
derived.cpp
#include "Derived.h"
CEREAL_REGISTER_TYPE(Derived)
template void Derived::serialize<cereal::BinaryOutputArchive>
( cereal::BinaryOutputArchive & ar, std::uint32_t const version );
template <class Archive>
void Derived::serialize(Archive & ar, std::uint32_t const version)
{
ar(cereal::base_class<Base>(this));
}
main.cpp
#include "Derived.h"
void main()
{
std::shared_ptr<Base> root(new Derived());
std::stringstream ss;
cereal::BinaryOutputArchive oarchive(ss);
oarchive(root);
}
problem
Project 1: Containts the base.* and derived.* and create a dll file. This dll is used by project 2
Project 2: Only contain main.cpp and link in the dll from project 1
When program is run the oarchive(root) will throw an "Trying to save an unregistered polymorphic type (class Derived)"