0

I realized an application under Linux:

  • using mostly Qt as library;
  • consisting of several libraries and a main gui application.

And as I'm making my code compliant to Visual Studio 2015's compiler I stumbled on the following dllexport problem (it is in fact a snipped code):

#include <QVariant>
#include <QList>

class SNIPPEDSHARED_EXPORT Snipped : public QList<QVariant>
{

public:
  Snipped();
};

SNIPPEDSHARED_EXPORT being the classical:

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

That code generating:

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

The error message is explicit enough and I even found people that have defined their own qHash:

What is troubling me:

  • I'm using QList and not qHash direcly; I'm well aware that QList may use qHash internally but the code runs smoothly with gcc: so it seems that Qt is providing what is required;
  • when I build the exact class in a regular binary (not a library one), all runs perfectly (either windows or linux).
  • when I removed the __declspec, then the library is building perfectly

I took time to read documentations about exporting templates as it seems the real problem (I even took time to read Qt source code (hey, their code is running :-))):

But the described problem doesn't seem to apply. I tried all kind of combinations but none did the trick (and it would have been a fluke).

The code being so short and simple, I think that I missed something basic (sorry: it is not really an interesting question and it is fustrating).

Has someone an idea?

P.S.: Full technical data:

  • Visual Studio 2015 Community Edition, with the last update: 14.0.25424.00 Update 3
  • Visual C++ 2015 00322-20000-00000-AA285
  • Using the Windows Kit 10: 10.0.10586.0
  • creation of an library project through 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
    
Community
  • 1
  • 1
lemmel
  • 132
  • 1
  • 6

1 Answers1

0

I found why I had this problem on « Microsoft Specific »: I quote:

When you declare a class dllexport, all its member functions and static data members are exported. You must provide the definitions of all such members in the same program. Otherwise, a linker error is generated.

And in order to be complete:

The one exception to this rule applies to pure virtual functions, for which you need not provide explicit definitions. However, because a destructor for an abstract class is always called by the destructor for the base class, pure virtual destructors must always provide a definition. Note that these rules are the same for nonexportable classes.

If you export data of class type or functions that return classes, be sure to export the class.

It will teach me not to glance over the documentation.

lemmel
  • 132
  • 1
  • 6