DLL的导出和继承

DLL export and inheritance in C++

本文关键字:继承 DLL      更新时间:2023-10-16

我想从DLL中导出一个类和它的基类,像这样:

#ifdef MY_EXPORTS
    #define DECLSPEC_TEST __declspec(dllexport)
#else
    #define DECLSPEC_TEST __declspec(dllimport)
#endif

class DECLSPEC_TEST BaseClass
{
  // stuff.
};
class DECLSPEC_TEST DerivedClass : public BaseClass
{
  // This class only has a constructor which initializes the class differently.
};

但是我试着在另一个DLL中使用这个类,我一直得到一个错误:

error LNK2019: unresolved external symbol 
"__declspec(dllimport) public: __thiscall DerivedClass::DerivedClass(void)"
 (__imp_??0DerivedClass@@QAE@XZ) referenced in function 
"public: __thiscall SomeOtherClass::SomeOtherClass(void)" (??0SomeOtherClass@@QAE@XZ)  

我还用PE资源管理器查看了我的导出DLL,我无法在导出列表中看到派生类。

当我尝试在我的其他DLL中使用基类时,它工作得很好。

我做错了什么?

有两种加载DLL的方法。第一种是从DLL中引用一个或多个符号(例如,您的类名),提供一个适当的导入. lib,并让链接器计算出一切。

第二种是通过LoadLibrary显式加载DLL。

两种方法都可以很好地用于c级函数导出。你可以让链接器处理它,也可以调用GetProcAddress。

但是当涉及到导出类时,通常只使用第一种方法,即隐式链接到DLL。

好吧,我不知道如何解释这个,但是我把派生类的构造函数的实现放在一个CPP文件中,而不是在类定义中,错误就消失了…
谢谢大家

链接器抱怨找不到DerivedClass的构造函数。尝试显式地声明它、定义它并从DLL中导出它:

DLL头文件:

class DECLSPEC_TEST BaseClass
{
};
class DECLSPEC_TEST DerivedClass : public BaseClass
{
public:
    DerivedClass();
};

DLL的cpp源文件:

DECLSPEC_TEST DerivedClass::DerivedClass() { }

在编译DLL时,还得到了一个.lib文件。这是您的导入库。您需要链接到它,以便连接到像这样的链接时间依赖项。

以下几点需要检查:

  1. 确保您正在链接到您从DLL项目中生成的EXACT . lib文件。它发生了,由于错误,我们构建了两个项目,但目标项目中的LIB文件是过时的。
  2. 确保DLL项目中相关的CPP文件得到编译。在所有方法上使用__declspec属性是而不是必需的,因为您导出的是整个类。
  3. 使用Dependency Walker,确保DLL实际上有类和它的所有方法导出。
  4. 确保在两个项目中的.LIB文件之间没有64位/32位不匹配

我看到的唯一缺失的东西是类声明之后的分号;。除此之外,导出应该可以正常工作。

还有一件事要检查:您是否在派生类中声明了构造函数为public ?

据我所知,在您的DerivedClass中,您声明了一个非默认构造函数(即与DerivedClass::DerivedClass()不同)。

在这种情况下,编译器不会为您生成默认构造函数,因此您必须定义一个,因为似乎出于某种原因,您正在使用DerivedClass的默认构造函数(可能在DerivedClass的实现中,不一定在使用DLL的代码中)。

没有必要在DLL接口中声明默认构造函数,但它应该在那里。

如果您不愿意使用默认构造函数,可以使用以下技巧:

在DerivedClass定义的private部分声明默认构造函数。

通过这种方式,任何使用它的尝试都会产生编译器错误(而不是链接器错误),这样您就知道在哪里尝试使用默认构造函数并可以修复它。

根据我的理解,我猜SomeOtherClass正试图调用你的BaseClass()的构造函数,这反过来又调用你的DerivedClass()的构造函数,但由于SomeOtherClass没有派生类的定义,所以它给出了一个错误,

可能的解决方案是在DervideClass中包含SomeOtherClass