C++ DLL中的静态数据
我的问题非常类似于:DLL中的类有一个静态成员。在本例中,静态成员的类型为(QT类型),并提供类的名称。我提供类级别的正常导出:C++ DLL中的静态数据,c++,windows,dll,linker,C++,Windows,Dll,Linker,我的问题非常类似于:DLL中的类有一个静态成员。在本例中,静态成员的类型为(QT类型),并提供类的名称。我提供类级别的正常导出:\uu declspec(dllexport) 当我将带有类的DLL链接到另一个项目并尝试编译它时,静态数据会出现“未解析的外部符号”错误。我证实了两件事: Dumpbin明确报告要由编译的DLL导出的静态数据成员 实际上,在报告错误的应用程序中似乎没有使用静态数据成员 DLL中的头文件(.h)是: class __declspec(dllexport) MyClass
\uu declspec(dllexport)
当我将带有类的DLL链接到另一个项目并尝试编译它时,静态数据会出现“未解析的外部符号”错误。我证实了两件事:
class __declspec(dllexport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
#include "MyClass.h"
MyClass::~MyClass() { }
const QString MyClass::JUST_A_NAME("call_me_al");
class __declspec(dllimport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
DLL中的实现文件(.cpp)是:
class __declspec(dllexport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
#include "MyClass.h"
MyClass::~MyClass() { }
const QString MyClass::JUST_A_NAME("call_me_al");
class __declspec(dllimport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
与post相比,我避免了内联方法,例如,实现显然不在标题中。类型(参见第83行及其后)本身包含多个内联线。这会导致错误吗
编辑:我在应用程序的标题中添加了导入语句。它位于任何包含之前。
应用程序中的头文件(.h)是:
class __declspec(dllexport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
#include "MyClass.h"
MyClass::~MyClass() { }
const QString MyClass::JUST_A_NAME("call_me_al");
class __declspec(dllimport) MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
错误保持不变:
error LNK2001: non resolved external symbol ""public: static class QString const MyClass::JUST_A_NAME" (?JUST_A_NAME@MyClass@@2VQString@@B)". <name of .obj file from application>
错误LNK2001:未解析的外部符号“public:静态类QString const MyClass::JUST_A_NAME”(?JUST_A_NAME@MyClass@@2VQString@@B)”。
在应用程序头文件中,您需要做两件事
\uuuu declspec(dllexport)
\uu declspec(dllimport)
#ifdef __COMPILING_MYLIB
#define MYLIBAPI __declspec(dllimport)
#else
#define MYLIBAPI __declspec(dllexport)
#endif
// mylib.h
class MYLIBAPI MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
然后像这样声明您的导出:
#ifdef __COMPILING_MYLIB
#define MYLIBAPI __declspec(dllimport)
#else
#define MYLIBAPI __declspec(dllexport)
#endif
// mylib.h
class MYLIBAPI MyClass {
public:
virtual ~MyClass();
static const QString JUST_A_NAME;
};
然后,在编译MYLIB时,将-D_ucompling_MYLIB
传递给编译器,这将触发上面的\if
这样,在编译库本身时,头文件会将对象声明为导出,但在编译将使用库的对象时,它们会声明为导入。我希望未解析的符号是
MyClass::JUST_A_NAME
,因为应用程序中不存在成员。但这不是问题的根源!您需要在使用应用程序中\u declspec(dllimport)
!我认为这足以让编译器知道您想要使用DLL中导出的成员。我要检查的第一件事是“dependencywalker”(www.dependencywalker.com),即符号是否实际在DLL中。然后,正如MFH正确指出的,您必须在导入和导出之间切换,这在您自己提供的链接中进行了解释。然后,但那只是模糊的记忆,我似乎记得,即使一个类通常是导出的,它的静态部分也不是,所以你必须显式地将导入/导出添加到它的声明中。是的,MFH,你对未解决错误的猜测是对的(参见编辑)。根据你的建议,我添加了一个\uu declspec(dllimport)
,但迄今为止没有成功。正如问题中提到的,我已经用dumpbin验证了丢失的符号肯定是在DLL中导出的。表示“[执行]类dllexport时,将导出其所有成员函数和静态数据成员。”