DLL中的静态数据

时间:2013-01-31 14:02:26

标签: c++ windows dll linker

我的问题与this one非常相似: DLL 中的类有静态成员。在这种情况下,静态成员是类型QString(QT类型)并为类提供名称。我在课程级别提供正常导出:__declspec(dllexport)

当我将DLL与我的类链接到另一个项目并尝试编译它时,我得到静态数据的“未解析的外部符号”错误。我验证了两件事:

  1. Dumpbin 肯定会报告由编译的DLL导出的静态数据成员。
  2. 实际上,静态数据成员似乎不会在报告错误的应用程序中使用。
  3. DLL中的HEADER文件(.h)为:

    class __declspec(dllexport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    DLL中的

    IMPLEMENTATION文件(.cpp)为:

    #include "MyClass.h"
    
    MyClass::~MyClass() { }
    const QString MyClass::JUST_A_NAME("call_me_al");
    

    already mentioned帖子相比,我避免使用内联方法,例如:实现显然不在标题中。类型QString(参见第83行ff。)本身包含几个内联。可能导致错误?

    编辑:我在应用程序的标题中添加了一个import语句。它位于任何包含之前。 APPLICATION中的 HEADER文件(.h)为:

    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>
    

1 个答案:

答案 0 :(得分:9)

在您的应用程序头文件中,您需要做两件事。

  1. 导出时,声明定义__declspec(dllexport)
  2. 导入时,声明定义__declspec(dllimport)
  3. 你显然不能同时做到这两点。

    你要做的是定义一个这样的宏:

    #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__COMPLING_MYLIB传递给编译器,这会触发上面的#if

    这样,在编译库本身时,头文件将事物声明为导出,但在编译将使用库的内容时,它们被声明为导入。