Issue correctly using CEREAL_REGISTER_DYNAMIC_INIT in C++ Cereal library

660 Views Asked by At

I've moved to using a lib file and wanted to make use of CEREAL_REGISTER_DYNAMIC_INIT properly. I don't know if I need to use this, but I noticed an issue with one of my cerealization types not being picked up properly in a separate DLL and thought this might help.

in accountActions.h I have the following at the end of the file:

CEREAL_FORCE_DYNAMIC_INIT(mv_clientactions);

In accountActions.cpp I have the following near the top of the file:

#include "clientActions.h"

#include "cereal/cereal.hpp"
#include "cereal/types/base_class.hpp"
#include "cereal/types/polymorphic.hpp"
#include "cereal/archives/adapters.hpp"

#include "cereal/archives/portable_binary.hpp"
#include "cereal/archives/json.hpp"

CEREAL_REGISTER_TYPE(CreatePlayer);
CEREAL_REGISTER_TYPE(LoginRequest);
CEREAL_REGISTER_TYPE(FindMatchRequest);
CEREAL_REGISTER_TYPE(ExpectedPlayersNoted);
CEREAL_REGISTER_DYNAMIC_INIT(mv_accountactions);

Assume mv_accountactions is just a completely made up string. I don't have any library or dll named that, but figured it is used to link these two units together? Documentation is sparse and I may be using this incorrectly.

The error I'm getting is this:

1> c:\git\bindstone\source\game\networklayer\accountactions.cpp(13): error C2084: function 'void cereal::detail::dynamic_init_dummy_mv_accountactions(void)' already has a body 1> c:\git\bindstone\source\game\networklayer\accountactions.h(127): note: see previous definition of 'dynamic_init_dummy_mv_accountactions'

I've double checked and am not using mv_accountactions anywhere else... I don't know what might cause this or how to resolve it. I'm wondering if I even need the CEREAL_REGISTER_DYNAMIC_INIT, or if there's a safe way to use it in case I do move to a DLL and I'm just misusing it.

Advice would be greatly appreciated.

Issue Opened Here: https://github.com/USCiLab/cereal/issues/523

1

There are 1 best solutions below

0
On BEST ANSWER

I seem to have been able to fix this by defining the CEREAL_FORCE_DYNAMIC_INIT with the previously missing CEREAL_DLL_EXPORT

Before (not working in VS 2017):

//! Forces dynamic initialization of polymorphic support in a
//! previously registered source file
/*! @sa CEREAL_REGISTER_DYNAMIC_INIT

    See CEREAL_REGISTER_DYNAMIC_INIT for detailed explanation
    of how this macro should be used.  The name used should
    match that for CEREAL_REGISTER_DYNAMIC_INIT. */
#define CEREAL_FORCE_DYNAMIC_INIT(LibName)              \
  namespace cereal {                                    \
  namespace detail {                                    \
    void dynamic_init_dummy_##LibName();                \
  } /* end detail */                                    \
  namespace {                                           \
    void dynamic_init_##LibName()                       \
    {                                                   \
      ::cereal::detail::dynamic_init_dummy_##LibName(); \
    }                                                   \
  } } /* end namespaces */

After (Fixed):

//! Forces dynamic initialization of polymorphic support in a
//! previously registered source file
/*! @sa CEREAL_REGISTER_DYNAMIC_INIT

    See CEREAL_REGISTER_DYNAMIC_INIT for detailed explanation
    of how this macro should be used.  The name used should
    match that for CEREAL_REGISTER_DYNAMIC_INIT. */
#define CEREAL_FORCE_DYNAMIC_INIT(LibName)              \
  namespace cereal {                                    \
  namespace detail {                                    \
    void CEREAL_DLL_EXPORT dynamic_init_dummy_##LibName();                \
  } /* end detail */                                    \
  namespace {                                           \
    void dynamic_init_##LibName()                       \
    {                                                   \
      ::cereal::detail::dynamic_init_dummy_##LibName(); \
    }                                                   \
  } } /* end namespaces */