1

I've started making an engine for my games and I have an error which I couldn't fix. Those are the files I have:

Game.h

#pragma once

#include "Core.h"

namespace Honey
{
    class HONEY_API Game
    {
    public:
        virtual void OnExecute() { }
        virtual void OnClose() { }
    };

    Game* CreateGamePtr();

    #define IMPLEMENT_BASIC_GAME() \
    Honey::Game* Honey::CreateGamePtr() \
    {\
        return new Honey::Game(); \
    }

    #define IMPLEMENT_GAME(GameClass) \
    Honey::Game* Honey::CreateGamePtr() \
    {\
        return new GameClass(); \
    }
}

Engine.h

#pragma once

#include "Core.h"

namespace Honey
{
    class Game;

    class HONEY_API Engine
    {
    public:
        static bool Init();
        void Update() const;
        bool Shutdown();

        inline static Engine* Get() { return s_Engine; }
        inline Game* GetGame() const { return m_Game; }
    private:
        inline static Engine* s_Engine = nullptr;
        Game* m_Game;
    };
}

Engine.cpp

#include "Engine.h"

#include "Game/Game.h"

namespace Honey
{
    extern Game* CreateGamePtr();

    bool Engine::Init()
    {
        if (Get() || !(s_Engine = new Engine()) || !(s_Engine->m_Game = CreateGamePtr()))
            return false;

        Get()->GetGame()->OnExecute();
        return true;
    }

    void Engine::Update() const
    {

    }

    bool Engine::Shutdown()
    {
        if (!Engine::Get() || !GetGame())
            return false;

        GetGame()->OnClose();
        delete this;

        return true;
    }
}

The project type is DLL. And when try to compile it, it gives me this linking error: LNK2019: unresolved external symbol "class Honey::Game __cdecl Honey::CreateGamePtr(void)" (?CreateGamePtr@Honey@@YAPEAVGame@1@XZ) referenced in function "public: static bool __cdecl Honey::Engine::Init(void)" (?Init@Engine@Honey@@SA_NXZ)*

and, LNK1120: 1 unresolved externals

The CreateGamePtr() is supposed to be declared in the game project so I'm externing it but it doesn't link. I've been trying to fix it for a long time now and nothing has worked so far.

trianglx
  • 89
  • 5
  • 2
    Probably this https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix section about microsoft specific import/export. – pptaszni Jul 18 '22 at 12:58
  • `s_Engine->m_Game = CreateGamePtr()` You call the function here but the linker can't find it when you are just building the dll. Maybe change the function so the caller needs to pass a `Game *` to it instead of calling `CreateGamePtr()`. – 001 Jul 18 '22 at 13:04
  • DLLs have to be complete. You can't just declare a missing function as extern and expect the DLL to link. – john Jul 18 '22 at 13:04
  • For instance you could change the `init` function so that it takes a pointer to the Game object. – john Jul 18 '22 at 13:06
  • Taking in a Game pointer fixed it. main (defined in "EntryPoint.h") calls the actual CreateGamePtr() and gives it as a parameter. And the file is included in the game project and now everything is fine. – trianglx Jul 18 '22 at 13:11

1 Answers1

0

In my opinion you have to declare "extern Game* CreateGamePtr()" in Engine.h and add global variable to Engine.cpp like this "Game* CreateGamePtr()".

Engine.h

#pragma once

#include "Core.h"

namespace Honey
{
    extern Game* CreateGamePtr();

    class Game;
    
    class HONEY_API Engine
    {
    public:
        static bool Init();
        void Update() const;
        bool Shutdown();

        inline static Engine* Get() { return s_Engine; }
        inline Game* GetGame() const { return m_Game; }
    private:
        inline static Engine* s_Engine = nullptr;
        Game* m_Game;
    };
}

Engine.cpp

#include "Engine.h"

#include "Game/Game.h"

namespace Honey
{
    Game* CreateGamePtr();

    bool Engine::Init()
    {
        if (Get() || !(s_Engine = new Engine()) || !(s_Engine->m_Game = CreateGamePtr()))
            return false;

        Get()->GetGame()->OnExecute();
        return true;
    }

    void Engine::Update() const
    {

    }

    bool Engine::Shutdown()
    {
        if (!Engine::Get() || !GetGame())
            return false;

        GetGame()->OnClose();
        delete this;

        return true;
    }
}

I hope this will help you.

CM-1207
  • 23
  • 7