无法从dll符号导出,否则这些符号完全有效

时间:2016-08-04 10:37:43

标签: c++ qt templates winapi dllexport

我在Linux下实现了一个应用程序:

  • 主要使用Qt作为库;
  • 由几个库和一个主要的gui应用程序组成。

由于我使我的代码符合Visual Studio 2015的编译器,我偶然发现了以下dllexport问题(它实际上是一个剪切代码):

#include <QVariant>
#include <QList>

class SNIPPEDSHARED_EXPORT Snipped : public QList<QVariant>
{

public:
  Snipped();
};

SNIPPEDSHARED_EXPORT是经典的:

#if defined(SNIPPED_LIBRARY)
#  define SNIPPEDSHARED_EXPORT __declspec(dllexport)
#else
#  define SNIPPEDSHARED_EXPORT __declspec(dllimport)
#endif

生成代码:

C:\Qt\5.7\msvc2015_64\include\QtCore\qhashfunctions.h:110: erreur : C2665: 'qHash': none of the 22 overloads could convert all the argument types
C:\Qt\5.7\msvc2015_64\include\QtCore\qhashfunctions.h:110: erreur : C2056: illegal expression

错误信息足够明确,我甚至找到了定义了自己的qHash的人:

令我感到不安的是:

  • 我使用QList而不是qHash直接使用;我很清楚QList可以在内部使用qHash,但代码可以使用gcc顺利运行:所以似乎Qt提供了所需的内容;
  • 当我在常规二进制文件(而不是库文件)中构建完全类时,所有操作都完美运行(无论是windows还是linux)。
  • 当我删除__declspec时,图书馆正在构建完美

我花时间阅读有关导出模板的文档,因为它似乎是真正的问题(我甚至花时间阅读Qt源代码(嘿,他们的代码正在运行: - ))):

但所描述的问题似乎并不适用。我尝试了所有类型的组合,但都没有做到这一点(而且它本来就是侥幸)。

代码简短而简单,我认为我错过了一些基本的东西(对不起:这不是一个有趣的问题而且很令人讨厌)。

有人有想法吗?

P.S。:完整的技术数据:

  • Visual Studio 2015社区版,上次更新时间:14.0.25424.00 Update 3
  • Visual C ++ 2015 00322-20000-00000-AA285
  • 使用Windows Kit 10:10.0.10586.0
  • 通过QtCreator创建图书馆项目
  • snipped.pro

    QT       -= gui
    TARGET   = snipped
    TEMPLATE = lib
    DEFINES += SNIPPED_LIBRARY
    SOURCES += snipped.cpp
    
  • snipped.cpp

    #include "snipped.h"
    #include <QDebug>
    
    Snipped::Snipped()
    {
      qDebug("Coucou !");/*some code is required otherwise the build will generate nothing*/
    }
    
  • snipped.h

    #ifndef SNIPPED_H
    #define SNIPPED_H
    
    #include "snipped_global.h"
    #include <QVariant>
    #include <QList>
    
    class SNIPPEDSHARED_EXPORT Snipped : public QList<QVariant>
    {
    public:
      Snipped();
    };
    
    #endif // SNIPPED_H
    
  • snipped_global.h

    #ifndef SNIPPED_GLOBAL_H
    #define SNIPPED_GLOBAL_H
    
    #include <QtCore/qglobal.h>
    
    #if defined(SNIPPED_LIBRARY)
    #  define SNIPPEDSHARED_EXPORT __declspec(dllexport)
    #else
    #  define SNIPPEDSHARED_EXPORT __declspec(dllimport)
    #endif
    
    #endif // SNIPPED_GLOBAL_H
    

1 个答案:

答案 0 :(得分:0)

我发现为什么我在«Microsoft Specific»上遇到了这个问题: 我引用:

  

当您声明类dllexport,所有其成员函数和   导出静态数据成员。您必须提供的定义   所有这些成员都在同一个程序中。否则,链接器错误是   生成。

为了完成:

  

此规则的一个例外适用于纯虚函数   您无需提供明确的定义。但是,因为一个   析构函数总是调用抽象类的析构函数   对于基类,纯虚拟析构函数必须始终提供   定义。请注意,这些规则对于不可移植的规则是相同的   类。

     

如果导出类类型的数据或返回类的函数,请执行   一定要出口班。

它会教我不要浏览文档。