好的,我开始明白为什么它被称为 Dll Hell。
这是我得到的代码
// API.h file
#ifdef EXPORTS
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
struct API IClass {
virtual void foo() = 0;
}
extern "C" API IClass* CreateClass(const char* type);
// Impl1.h
class Impl1: public IClass
{
//...
}
// API.cpp file
#include "Impl1.h"
#include "Impl2.h"
#include "ImplX.h"
extern "C" API IClass* CreateClass(const char* type)
{
if (type == "type1")
return new Impl1();
// ...
return 0;
}
我收到链接器警告
warning LNK4217: locally defined symbol ??0IClass@DG@@QAE@XZ (public: __thiscall IClass::IClass(void)) imported in function...
我知道发生这种情况是因为我已经在所有 Impl 中导入了这些符号,但另一方面,它们现在是本地的,因为我正在作为 API 一部分的工厂中编译它们。
1)我应该忽略警告还是有不同的方法来解决这个问题?
2)我应该保留默认的 __thiscall 还是更改为 __stdcall ?
编辑
不导出IClass
帮助我删除了警告。
另一个问题出现了,我不确定同样的方法可以解决这个问题。
让我们假设IClass
也有一个方法virtual bar(IData* data) = 0
。
如果我希望客户能够创建实例,IData
我需要将其导出到 dll 中,回到 impl 中的原始问题。除非我也为它们创建创建函数,但这对于简单的数据结构来说似乎有点太多开销。
所以基本上问题是,如何在IData
不将它们导出到 DLL 的情况下向客户端公开?