0
\$\begingroup\$

I'm making a multiplayer game, the Server stores it's game world state as various std::unordered_map in a class called ServerWorldState.

The server is composed by a single class called Game, which contains ServerWorldState.

Currently I'm trying to make Save() and Load() functions, which for now will be in the Game class. These functions are supposed to save certain data from the maps within ServerWorldState into a binary archive, for this purpose, I'm using Cereal library for serialization and the standard file IO streams.

Cereal requires a serialize method to be present in a class, in order for members to be specified for serialization:

ServerWorldState.h

class ServerWorldState : public World
{
private:
    std::unordered_map<int, ServerProp> props;
public:
    template<class Archive>
    void serialize(Archive& archive);

};

ServerWorldState.cpp

template<class Archive>
void ServerWorldState::serialize(Archive& archive)
{
    archive(props); //Serialize things by passing them to the archive
}

The ServerProp class actually has another serialize method within itself. I'm unsure if this is correct for specifying with further depth what object members should get serialized.

Save function from Game (load works very similar and has same problem, but since I haven't finished it's design I'm only showing save):

Game.h

class Game
{
private:
    std::shared_ptr<ServerWorldState> currentWorld;
public:
    bool Save();
};

Game.cpp

bool Game::Save()
{
    std::ofstream outfile("level.dat", std::ios::binary | std::ios::out);
    if (!outfile) {
        std::cout << "SERVER_WORLD_STATE::SAVE: Could not open world.dat file for saving!" << std::endl;
        return false;
    }

    {
        cereal::PortableBinaryOutputArchive oarchive(outfile); //Create an output archive

        oarchive(currentWorld); //Write data to the archive

    } //Archive goes out of scope, ensuring all contents are flushed

    outfile.close();

    return true;
}

In essence I want to serialize/deserialize and binary save/load the std::unordered_map in ServerWorldState, but I get this link error:

Error LNK2019 unresolved external symbol "public: void __cdecl ServerWorldState::serialize(class cereal::PortableBinaryOutputArchive &)" (??$serialize@VPortableBinaryOutputArchive@cereal@@@ServerWorldState@@QEAAXAEAVPortableBinaryOutputArchive@cereal@@@Z) referenced in function "public: static void __cdecl cereal::access::member_serialize(class cereal::PortableBinaryOutputArchive &,class ServerWorldState &)" (??$member_serialize@VPortableBinaryOutputArchive@cereal@@VServerWorldState@@@access@cereal@@SAXAEAVPortableBinaryOutputArchive@1@AEAVServerWorldState@@@Z) - Game.obj line 1

I would asume this would show if the serialize method wasn't defined, but it is. I also thought I might be missing some inclusion, but I seem to have all in order.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ The linker can't see template definitions in source files. \$\endgroup\$ Commented May 25, 2020 at 4:16
  • \$\begingroup\$ indeed it may be because of the deported definition, building ServerWorldState.cpp will be fine but not Game.cpp and ServerWorldState.cpp together. put the def inline in the .h to check? \$\endgroup\$ Commented May 25, 2020 at 8:41
  • \$\begingroup\$ Yes, having the method definition in the .h actually fixes this. Not entirely sure how I feel about the actual definition being in the .h though. I actually read it may be faster, but I'm used to always having definitions in .cpp \$\endgroup\$ Commented May 25, 2020 at 15:50

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.