我有一个我移植到Windows / MSVC的库。该库是C ++,并使用以下模式隐藏实现。我尝试使用建议的方法在类声明中使用dllexport
导出整个类。
#define API __declspec(dllexport)
class API Something
{
public:
static Something * instantiate();
void doSomething() = 0;
// etc
};
然后有一个私有实现,它实现静态工厂方法和所有其他方法。
// SomethingImpl.h
class SomethingImpl : public Something
{
//... normal overrides
}
// SomethingImpl.cpp
Something * SomethingImpl::instantiate()
{
return new SomethingImpl();
}
void SomethingImpl::doSomething()
{
// something great
}
但是,当我认为将DLL链接到我的应用程序时,链接器找不到所有这些符号(LNK2019)。我想因为它们是纯粹的虚拟方法,所以假设它们不需要它们?任何提示?
其他更正常的类正在链接OK,当我在依赖walker中看到DLL时,这些类的符号肯定不存在。
由于
答案 0 :(得分:1)
从某种意义上说,您的假设是正确的,即基类(Something
)不会被导出。更具体地说,没有为基类生成实际代码(因为它是纯虚拟类)。因此,没有可以导出的符号。
在派生类(SomethingImpl
)上,您必须为dll的使用者dllexport私有实现。基类的dllexport不是由派生类继承的。但是,您必须导出这些符号,以便允许消费者实际使用此代码。这并不意味着您的实施细节对消费者来说是“公开的”。
例如,假设您的dll的使用者声明了一个类型为Something
的成员的类。当此类调用Something::instantiate()
时,链接器需要知道需要调用哪个实际地址。因此,必须导出您的实现。