c++ - 使用 std::make_shared 创建奇怪的链接器异常
问题描述
我想让用户能够为绘图对象创建渲染器。但是,'return std::make_shared(this);' 行 创建一个奇怪的链接器错误。我没修好。
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
如果我替换该行 return std::make_shared(this); 返回 nullptr;出于测试目的,它运行。所以我最终假设这条线是这个错误的原因。我试过这样想,删除 ENGINE_API 定义,它将方法导出到 dll 中。但这不是这个错误的原因。
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()
{
}
}
有人知道,我该如何解决这个异常?
使用 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()
{
}
}
解决方案
我找到了这个链接器异常的原因。我在同一个 dll 中使用了两个同名的类。我用我的项目的层次结构详细解释它:
-Engine (Project and DLL)
-- Vulkan (Folder)
--- VulkanRenderer.cpp
--- VulkanRenderer.h
- VulkanRenderer.cpp
- VulkanRenderer.h
文件夹 Vulkan 中的文件是使用独特的 Vulkan 功能构建的类。根文件夹中的 VulkanRenderer 将此函数包装在具有接口的工厂中。问题是两个cpp文件在编译过程中都有冲突。
推荐阅读
- android - 没有数据库的收藏夹android studio
- r - 使用 mclapply 或 %dopar% 从对角线切片组装矩阵,例如 Matrix::bandSparse
- sql - 在 sql 中编写查询并在 Webi 报告中实现它
- c++ - 我应该在字符串上使用追加还是通过加法分配?
- xcode - Xcode 版本编辑器中突出显示的文本使文本不可读
- css - 新手希望制作这种时尚的鼠标悬停效果
- android - Apache HTTP 库在 API 27 中不起作用
- elasticsearch - 使用子聚合桶问题的 KIBANA 拆分条形图
- python - Python程序用户定义函数
- sql - Powershell WQL 查询 (SCCM) 如何在两个 WHERE 上进行过滤?