我有一个基类 (QIndicator
),我想在 DLL 中实现派生类。 Visual Studio 2012 中用于示例派生类的 DLL 项目具有以下代码:
带有基类的头文件
#ifndef _DLL_COMMON_INDICATOR_
#define _DLL_COMMON_INDICATOR_
// define the DLL storage specifier macro
#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
class QIndicator
{
private:
int x;
int y;
};
extern "C"
{
// declare the factory function for exporting a pointer to QIndicator
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
#endif
带有派生类的源文件
#define DLL_EXPORT
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
public:
QIndicatorDer (void) : QIndicator(){};
~QIndicatorDer (void){};
private:
// list of QIndicatorDer parameters
int x2;
int y2;
};
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
我遇到的问题是,在成功构建后,生成的 DLL 文件不包含导出的 getIndicatorPtr
函数(如 DependencyWalker 所示)。我检查了 dllexport
关键字是否正确地传播到 getIndicatorPtr
的声明中,它的确如此。
另一个有趣的问题是我已经有另一个这样的派生类,在我几个月前创建的另一个 DLL 项目中。这个旧项目基本上是一样的,一切都很好。我检查了旧项目和当前项目的所有属性,它们看起来完全相同。所以我想不出为什么我不能让 getIndicatorPtr
导出。
非常感谢任何帮助, 丹尼尔
最佳答案
那是因为它没有被导出。为什么?
__declspec
说明符只能放在函数的声明中,而不是它的定义中。此外,避免使用类似#define DLL_EXPORT
的内容。预处理器定义应在项目属性 (MSVC) 或命令行选项(例如 GCC 中的 -D
)中定义。
看看你的代码:
标题
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
当编译器解析此 header 时,会将 DECLDIR
视为 dllimport
(因为您在 .cpp
中定义了 DLL_EXPORT
).然后在.cpp
中,突然出现了dllexport
。用的是哪一个?第一个。
因此,保留标题(没问题),但更改来源:
//#define DLL_EXPORT -> remove this!
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
//...
};
extern "C"
{
/* DECLDIR -> and this! */ QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
然后,转到项目属性(我假设您使用的是 Visual Studio),然后是 C/C++
-> Preprocessor
-> Preprocessor Definitions
并在那里添加 DLL_EXPORT=1
。
这应该有效。
关于c++ - 尽管 dllExport 正确,但没有函数导出到 DLL - Visual Studio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29471901/