【问题标题】:Using __declspec(dllimport) in a class containing a static member of its own type在包含其自身类型的静态成员的类中使用 __declspec(dllimport)
【发布时间】:2016-06-09 01:03:06
【问题描述】:

我有一个标题如下所示的类:

class MYCLASS_DECLSPEC MyClass
{
    MyClass(int x);

    ....

    static const MyClass Zero;
}

在实现文件上我初始化了静态常量成员:

const A A::Zero(0);

现在我想将此代码编译为 DLL,有时编译为静态库。通常的做法是像这样定义 MYCLASS_DECLSPEC:

#ifdef BUILDING_MYDLL
#define MYCLASS_DECLSPEC __declspec(dllexport)
#else
#define MYCLASS_DECLSPEC __declspec(dllimport)
#endif

当我将此代码编译为 DLL(定义了 BUILDING_MYDLL)时,一切正常。但是当我将此代码编译为静态库(未定义 BUILDING_MYDLL)时,出现以下错误:

error: definition of static data member 'MyClass::Zero' of dllimport'd class

如果我完全删除 __declspec(dllimport),代码将成功编译为静态库。

我在 Windows 7 上使用 mingw32 编译器。

有人能解释一下为什么会发生这种情况以及如何解决吗?

【问题讨论】:

  • 预处理器符号BUILDING_MYDLL 不会在 DLL 和静态库之间切换。它将MYCLASS_DECLSPEC 的含义切换为导出符号(在构建DLL 时)或在编译链接到该DLL 的客户端时导入符号。由于您的心理模型有缺陷,我不知道该怎么回答这个问题。这没有多大意义。
  • 是的,我知道符号 BUILDING_MYDLL 切换 MYCLASS_DECLSPEC。 makefile 应该定义BUILDING_MYDLL 以编译为 DLL,或者不定义它以编译为静态库。 “心智模型有缺陷”是什么意思?我的问题中缺少哪些信息以使其更清楚?
  • 如果未定义BUILDING_MYDLL,您不是构建静态库,而是客户端代码导入 DLL中的符号。请参阅Importing and Exporting 以了解您的代码的真正作用。
  • 我读了更多,我想我开始明白了。但是我还是不明白__declspec(dllimport) 是做什么用的:假设我正在构建一个共享库;所以我想使用__declspec(dllexport)导出类/方法,那么使用ifdef的常见做法需要什么:#ifdef BUILDING_MYDLL #define MYCLASS_DECLSPEC __declspec(dllexport) #else #define MYCLASS_DECLSPEC __declspec(dllimport) #endif
  • __declspec(dllimport) 用于客户端,即使用您的库的应用程序。如果您正在构建(或使用)静态库,则需要将 MYCLASS_DECLSPEC 定义为空字符串。静态库不使用__declspec

标签: c++ windows mingw dllimport


【解决方案1】:

我认为我们将#defines 放在另一个#define 中:

#ifdef _DLL
#ifdef BUILDING_MYDLL
#define MYCLASS_DECLSPEC __declspec(dllexport)
#else
#define MYCLASS_DECLSPEC __declspec(dllimport)
#endif
#else
#define MYCLASS_DECLSPEC
#endif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多