-1

I want to give the user the ability to create a Renderer for drawing objects. But, the line 'return std::make_shared(this);' creates a strange linker error. I don't get it fixed.

1>   Creating library ..\..\..\bin\Debug\Invision.lib and object ..\..\..\bin\Debug\Invision.exp
1>VulkanEngine.obj : error LNK2019: unresolved external symbol "public: __cdecl engine_namespace::VulkanRenderer::VulkanRenderer(class engine_namespace::VulkanEngine *)" (??0VulkanRenderer@engine_namespace@@QEAA@PEAVVulkanEngine@1@@Z) referenced in function "public: __cdecl std::_Ref_count_obj<class engine_namespace::VulkanRenderer>::_Ref_count_obj<class engine_namespace::VulkanRenderer><class engine_namespace::VulkanEngine *>(class engine_namespace::VulkanEngine * &&)" (??$?0PEAVVulkanEngine@engine_namespace@@@?$_Ref_count_obj@VVulkanRenderer@engine_namespace@@@std@@QEAA@$$QEAPEAVVulkanEngine@Invision@@@Z)
1>..\..\..\bin\Debug\Invision.dll : fatal error LNK1120: 1 unresolved externals

If I replace the line return std::make_shared(this); with return nullptr; for testing purposes, it runs. So I finally assume that this line is the reason for this error. I tried thinks like, removing the ENGINE_API definiton, which exports the method in to a dll. But it was not the reason for this error.

VulkanEngine.cpp

#include "precompiled.h"


#include "VulkanEngine.h"
#include "IRenderer.h"
#include "VulkanRenderer.h"


namespace engine_namespace
{


    VulkanEngine::VulkanEngine(CanvasDimensions canvas) :
        IGraphicsEngine(EngineType::Vulkan, "Vulkan", "1.2.137", canvas)
    {
        …
    }

    std::shared_ptr <IRenderer> VulkanEngine::create_renderer()
    {
        return  std::make_shared<VulkanRenderer >(this);
    }

    VulkanEngine::~VulkanEngine()
    {
        …
    }

}

VulkanEngine.h

#ifndef VULKAN_ENGINE_H
#define VULKAN_ENGINE_H

#include <memory>
#include "IGraphicsEngine.h"
#include "renderer\Vulkan\InVulkan.h"
#include "renderer\Vulkan\VulkanException.h"
#include "renderer\Vulkan\VulkanInstance.h"
#include "renderer\Vulkan\VulkanDevice.h"
#include "renderer\Vulkan\VulkanPresentation.h"

#include "Vulkan/Vulkan.h"

namespace engine_namespace
{
    

    class VulkanRenderer;

    …

    class VulkanEngine : public IGraphicsEngine
    {
    private:
        engine_namespace::VulkanInstance vulkanInstance;
        engine_namespace::SVulkan vulkInstance;

    public:
        ENGINE_API VulkanEngine(CanvasDimensions canvas);
        ENGINE_API std::shared_ptr <IRenderer> create_renderer() override;
        ENGINE_API ~VulkanEngine();

    };

}
#endif //VulkanEngine

VulkanRenderer.h

#ifndef VULKAN_RENDERER_H
#define VULKAN_RENDERER_H


#include "IRenderer.h"
namespace engine_namespace
{
    class VulkanEngine;
    class VulkanRenderer : public IRenderer
    {
    public:

        ENGINE_API VulkanRenderer(VulkanEngine* engine);

        ENGINE_API void render() override;
    };

}

#endif // VULKAN_RENDERER_H

VulkanRenderer.cpp

#include "precompiled.h"

#include "VulkanEngine.h"

#include "VulkanRenderer.h"
namespace engine_namespace
{
    VulkanRenderer::VulkanRenderer(VulkanEngine* engine) :
        IRenderer(engine)
    {
    }

    void VulkanRenderer::render()
    {
        
    }
}

Does someone know, how I can fix this exception?

After changing using shared_from_this()

VulkanEngine.cpp

#include "precompiled.h"


#include "VulkanEngine.h"
#include "IRenderer.h"
#include "VulkanRenderer.h"


namespace engine_namespace
{


    VulkanEngine::VulkanEngine(CanvasDimensions canvas) :
        IGraphicsEngine(EngineType::Vulkan, "Vulkan", "1.2.137", canvas)
    {
        …
    }

    std::shared_ptr <IRenderer> VulkanEngine::create_renderer()
    {
        return  std::make_shared<VulkanRenderer >(shared_from_this());
    }

    VulkanEngine::~VulkanEngine()
    {
        …
    }

}

VulkanEngine.h

#ifndef VULKAN_ENGINE_H
#define VULKAN_ENGINE_H

#include <memory>
#include "IGraphicsEngine.h"
#include "renderer\Vulkan\InVulkan.h"
#include "renderer\Vulkan\VulkanException.h"
#include "renderer\Vulkan\VulkanInstance.h"
#include "renderer\Vulkan\VulkanDevice.h"
#include "renderer\Vulkan\VulkanPresentation.h"

#include "Vulkan/Vulkan.h"

namespace engine_namespace
{
    

    class VulkanRenderer;

    …

    class VulkanEngine : public IGraphicsEngine, std::enable_shared_from_this<VulkanEngine >
    {
    private:
        engine_namespace::VulkanInstance vulkanInstance;
        engine_namespace::SVulkan vulkInstance;

    public:
        ENGINE_API VulkanEngine(CanvasDimensions canvas);
        ENGINE_API std::shared_ptr <IRenderer> create_renderer() override;
        ENGINE_API ~VulkanEngine();

    };

}
#endif //VulkanEngine

VulkanRenderer.h

#ifndef VULKAN_RENDERER_H
#define VULKAN_RENDERER_H


#include "IRenderer.h"
namespace engine_namespace
{
    class VulkanEngine;
    class VulkanRenderer : public IRenderer
    {
    public:

        ENGINE_API VulkanRenderer(std::shared_ptr<VulkanEngine> engine);

        ENGINE_API void render() override;
    };

}

#endif // VULKAN_RENDERER_H

VulkanRenderer.cpp

#include "precompiled.h"

#include "VulkanEngine.h"

#include "VulkanRenderer.h"
namespace engine_namespace
{
    VulkanRenderer::VulkanRenderer(std::shared_ptr<VulkanEngine> engine) :
        IRenderer(engine)
    {
    }

    void VulkanRenderer::render()
    {
        
    }
}
Pixma
  • 11
  • 2
  • Does this answer your question? [C++11 Passing 'this' as paramenter for std::make\_shared](https://stackoverflow.com/questions/10534220/c11-passing-this-as-paramenter-for-stdmake-shared) – Anya Shenanigans Jun 29 '20 at 16:18
  • It looks like you mixed up the labels for VulkanRenderer.h and .cpp. – Stephen Newell Jun 29 '20 at 16:18
  • I think you may be looking for [std::enable_shared_from_this](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this) and [std::shared_from_this](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this). – Jesper Juhl Jun 29 '20 at 16:35
  • @Petesh Thanks, for your advice. I implemented this by changing the pointers to std::shared_ptr and I use shared_from_this() instead of this. But I get the same linker exception. – Pixma Jun 29 '20 at 16:39
  • @StephenNewell thanks for your advice, I fixed the labels :) – Pixma Jun 29 '20 at 16:49
  • Your problem has nothing to do with `shared_ptr`. It looks like something is going wrong with your `ENGINE_API` macro. Try replacing the `return std::make_shared(this);` with `VulkanRenderer(this); return nullptr;`. Your linker can't find the `VulkanRenderer` constructor. – Chronial Jun 29 '20 at 17:00
  • Are you building VulkanRenderer.cpp? – Stephen Newell Jun 29 '20 at 17:03
  • @Chronial You are right. I changed the codeslines to your Suggestion. I found out, the VulkanRenderer(this); raises the exception. But I have no clue what is wrong with the constructor of the class VulkanEngine. The ENGINE_API stays for #define ENGINE_API __declspec(dllexport) – Pixma Jun 29 '20 at 17:10
  • @StephenNewell Yes, during the building process. Visual Studio prints: ... 1>IGraphicsEngine.cpp 1>IRenderer.cpp 1>VulkanRenderer.cpp 1>InVulkan.cpp ... – Pixma Jun 29 '20 at 17:11

1 Answers1

0

I found the reason for this linker exception. I used two classes with the same name in the same dll. I explain it in detail with the hierarchy of my project:

-Engine (Project and DLL)
-- Vulkan (Folder)
--- VulkanRenderer.cpp
--- VulkanRenderer.h
- VulkanRenderer.cpp
- VulkanRenderer.h

Files in the Folder Vulkan are classes which are built with the unique Vulkan Functionalities. The VulkanRenderer in the Root Folder wraps this functions in a Factory with an Interfaces. The problem was that both cpp files had a conflict during the compilation process.

Pixma
  • 11
  • 2