DLL的导出和继承
DLL export and inheritance in C++
我想从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文件。这是您的导入库。您需要链接到它,以便连接到像这样的链接时间依赖项。
以下几点需要检查:
- 确保您正在链接到您从DLL项目中生成的EXACT . lib文件。它发生了,由于错误,我们构建了两个项目,但目标项目中的LIB文件是过时的。
- 确保DLL项目中相关的CPP文件得到编译。在所有方法上使用
__declspec
属性是而不是必需的,因为您导出的是整个类。 - 使用Dependency Walker,确保DLL实际上有类和它的所有方法导出。
- 确保在两个项目中的.LIB文件之间没有64位/32位不匹配
我看到的唯一缺失的东西是类声明之后的分号;
。除此之外,导出应该可以正常工作。
还有一件事要检查:您是否在派生类中声明了构造函数为public
?
据我所知,在您的DerivedClass
中,您声明了一个非默认构造函数(即与DerivedClass::DerivedClass()
不同)。
在这种情况下,编译器不会为您生成默认构造函数,因此您必须定义一个,因为似乎出于某种原因,您正在使用DerivedClass
的默认构造函数(可能在DerivedClass的实现中,不一定在使用DLL的代码中)。
没有必要在DLL接口中声明默认构造函数,但它应该在那里。
如果您不愿意使用默认构造函数,可以使用以下技巧:
在DerivedClass定义的private
部分声明默认构造函数。
通过这种方式,任何使用它的尝试都会产生编译器错误(而不是链接器错误),这样您就知道在哪里尝试使用默认构造函数并可以修复它。
根据我的理解,我猜SomeOtherClass正试图调用你的BaseClass()的构造函数,这反过来又调用你的DerivedClass()的构造函数,但由于SomeOtherClass没有派生类的定义,所以它给出了一个错误,
可能的解决方案是在DervideClass中包含SomeOtherClass
- 继承函数的重载解析
- 挂起和取消挂起一个文件DLL
- 继承期间显示未知行为的子类
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 头文件-继承c++
- 从C++dll访问C#中的一行主要参数
- 为什么在保护模式下继承升级不起作用
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 从模板继承的 MSVC DLL 导出类会导致LNK2005已定义的错误
- python永远不能调用包含继承逻辑的c++dll或左右文件
- 从导出到 DLL 的类继承时C++缺点
- 从从模板继承的dll导出类
- 代理dll:方法覆盖/方法转发(COM实现继承)
- 链接器错误:DLL和继承
- DLL的导出和继承