Inconsistent dll linkage



  • Hi guys, I have a project with subdirs, myproject, pluginmanager, pluginfoo.

    I have a header file called pluginmanager_global.hpp with this:

    #ifndef PLUGINMANAGER_GLOBAL_HPP
    #define PLUGINMANAGER_GLOBAL_HPP
    
    #include <QtCore/qglobal.h>
    
    #if defined(MYPROJECT_LIBRARY)
    #  define MYPROJECT_EXPORT Q_DECL_EXPORT
    #else
    #  define MYPROJECT_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // PLUGINMANAGER_GLOBAL_HPP
    

    I created another library called core with core_global.hpp with the same content of pluginmanager_global.hpp and I wanted to remove pluginmanager_global.hpp then I included on the pro file and tried to use the header but I'm getting an error saying:

    PluginManager::qt_static_metacall inconsistent dll linkage

    staticMetaObject: inconsistent dll linkage

    ...

    PluginManager::staticMetaObject: definition of dllimport static data member not allowed

    Why can't I use a simple header from another library with the exactly same content?


  • Moderators

    @Defohin Did you run qmake and did you a complete rebuild after these changes?



  • Yes, I did and nothing... The error continues.


  • Lifetime Qt Champion

    Hi,

    Did you properly define MYPROJECT_LIBRARY when building the library and not when using it ?



  • @SGaist Yes, DEFINES += CORE_LIBRARY in the core library and DEFINES += PLUGINMANAGER_LIBRARY in the pluginmanager.


  • Lifetime Qt Champion

    Can you exactly how your project is organised ?



  • @SGaist https://forum.qt.io/topic/75042/abstract-plugin-inheritance-error/14

    I created another library called core that is not listed there and create the core_global.hpp, tried to include that header on the pluginmanager and I get the errors... - core_global.hpp has the same content as pluginmanager_global.hpp but it only works with it, not with core_global.hpp.



  • Check if your plugin class inherited from QObject and Q_OBJECT is included in private section



  • @dheerendra I don't think that it has anything to do with the plugins, and the plugins doesn't inherent from QObject cause AbstractPlugin does that already and if I make a plugin inherent from QObject as well the compiler throws me a warning saying that the two of them is inheriting the same class.


  • Lifetime Qt Champion

    Did you adjust the define value when changing the header ?



  • @SGaist Yes, I did, both the files are exactly equal, the only thing that changes is CORE_LIBRARY and PLUGINMANAGER_LIBRARY, and they are both defined on their related pro files. I just can't use the header from one library on the other one and these errors happen.


  • Lifetime Qt Champion

    What do you mean by you can't use the header ? What exactly goes wrong ?



  • @SGaist I get the errors mentioned above about inconsistent dll linkage.

    I'm going to post the entire working code and then I will post the change so you can see what is going on.

    Here is the link to download the entire project: download

    That is how the structure looks like:

    |-- myproject
        |-- myproject.pro
        |-- core
        |   |-- core.pro
        |   |-- core_global.hpp
        |-- myproject
        |   |-- main.cpp
        |   |-- myproject.pro
        |   |-- myprojectwindow.cpp
        |   |-- myprojectwindow.hpp
        |-- pluginmanager
        |   |-- abstractplugin.cpp
        |   |-- abstractplugin.hpp
        |   |-- plugininterface.hpp
        |   |-- pluginmanager.cpp
        |   |-- pluginmanager.hpp
        |   |-- pluginmanager.pro
        |   |-- pluginmanager_global.hpp
        |-- plugins
            |-- plugins.pro
            |-- pluginfoo
                |-- pluginfoo.cpp
                |-- pluginfoo.hpp
                |-- pluginfoo.json
                |-- pluginfoo.pro
    

    myproject.pro

    TEMPLATE = subdirs
    SUBDIRS  = core \
               pluginmanager \
               plugins \
               myproject
    CONFIG  += ordered
    

    core.pro

    QT      += core
    TARGET   = core
    TEMPLATE = lib
    DEFINES += CORE_LIBRARY
    
    DESTDIR  = $$OUTPWD/bin
    
    HEADERS += core_global.hpp
    

    core_global.hpp

    #ifndef CORE_GLOBAL_HPP
    #define CORE_GLOBAL_HPP
    
    #include <QtCore/qglobal.h>
    
    #if defined(CORE_LIBRARY)
    #  define MYPROJECT_EXPORT Q_DECL_EXPORT
    #else
    #  define MYPROJECT_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // CORE_GLOBAL_HPP
    

    main.cpp

    #include "myprojectwindow.hpp"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication application(argc, argv);
    
        MyProjectWindow window;
        window.show();
    
        return application.exec();
    }
    

    myproject.pro

    QT      += core gui widgets xml network
    TARGET   = myproject
    TEMPLATE = app
    DEFINES += QT_DEPRECATED_WARNINGS
    DEFINES += MYPROJECT_LIBRARY
    
    INCLUDEPATH += ../core ../pluginmanager
    DESTDIR      = $$OUTPWD/bin
    LIBS        += -L$$OUTPWD/bin -lcore -lpluginmanager
    
    HEADERS   += myprojectwindow.hpp
    SOURCES   += main.cpp \
                 myprojectwindow.cpp
    

    myprojectwindow.cpp

    #include "myprojectwindow.hpp"
    
    MyProjectWindow::MyProjectWindow(QWidget *parent) : QMainWindow(parent)
    {
    
    }
    

    myprojectwindow.hpp

    #ifndef MYPROJECTWINDOW_HPP
    #define MYPROJECTWINDOW_HPP
    
    #include <QMainWindow>
    
    class MyProjectWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MyProjectWindow(QWidget *parent = 0);
    };
    
    #endif // MYPROJECTWINDOW_HPP
    

    abstractplugin.cpp

    #include "abstractplugin.hpp"
    

    abstractplugin.hpp

    #ifndef ABSTRACTPLUGIN_HPP
    #define ABSTRACTPLUGIN_HPP
    
    #include "plugininterface.hpp"
    
    class MYPROJECT_EXPORT AbstractPlugin : public QObject, public PluginInterface
    {
        Q_OBJECT
        Q_INTERFACES(PluginInterface)
    };
    
    #endif // ABSTRACTPLUGIN_HPP
    

    plugininterface.hpp

    #ifndef PLUGININTERFACE_HPP
    #define PLUGININTERFACE_HPP
    
    #include "pluginmanager_global.hpp"
    #include <QObject>
    
    class MYPROJECT_EXPORT PluginInterface
    {
    public:
        virtual ~PluginInterface() {}
    };
    
    #define PluginInterface_iid "PluginInterface/1.0"
    
    Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
    
    #endif // PLUGININTERFACE_HPP
    

    pluginmanager.cpp

    #include "pluginmanager.hpp"
    
    PluginManager::PluginManager(QObject *parent) : QObject(parent)
    {
    
    }
    

    pluginmanager.hpp

    #ifndef PLUGINMANAGER_HPP
    #define PLUGINMANAGER_HPP
    
    #include "pluginmanager_global.hpp"
    #include <QObject>
    
    class MYPROJECT_EXPORT PluginManager : public QObject
    {
        Q_OBJECT
    
    public:
        explicit PluginManager(QObject *parent = 0);
    };
    
    #endif // PLUGINMANAGER_HPP
    

    pluginmanager.pro

    QT      += core
    TARGET   = pluginmanager
    TEMPLATE = lib
    DEFINES += PLUGINMANAGER_LIBRARY
    
    INCLUDEPATH += ../core
    DESTDIR      = $$OUTPWD/bin
    
    SOURCES += abstractplugin.cpp \
               pluginmanager.cpp
    HEADERS += pluginmanager_global.hpp \
               abstractplugin.hpp \
               pluginmanager.hpp \
               plugininterface.hpp
    

    pluginmanager_global.hpp

    #ifndef PLUGINMANAGER_GLOBAL_HPP
    #define PLUGINMANAGER_GLOBAL_HPP
    
    #include <QtCore/qglobal.h>
    
    #if defined(PLUGINMANAGER_LIBRARY)
    #  define MYPROJECT_EXPORT Q_DECL_EXPORT
    #else
    #  define MYPROJECT_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // PLUGINMANAGER_GLOBAL_HPP
    

    plugins.pro

    TEMPLATE = subdirs
    SUBDIRS  = pluginfoo
    

    pluginfoo.cpp

    #include "pluginfoo.hpp"
    

    pluginfoo.hpp

    #ifndef PLUGINFOO_HPP
    #define PLUGINFOO_HPP
    
    #include "abstractplugin.hpp"
    
    class PluginFoo : public AbstractPlugin
    {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "pluginfoo.json") \
        Q_INTERFACES(PluginInterface)
    };
    
    #endif // PLUGINFOO_HPP
    

    pluginfoo.json

    {}
    

    pluginfoo.pro

    QT          += core gui
    TARGET       = pluginfoo
    TEMPLATE     = lib
    CONFIG      += plugin
    DEFINES     += QT_DEPRECATED_WARNINGS
    
    INCLUDEPATH += ../../core ../../pluginmanager
    DESTDIR      = $$OUTPWD/bin/plugins
    LIBS        += -L$$OUTPWD/bin -lcore -lpluginmanager
    
    SOURCES     += pluginfoo.cpp \
                   pluginfoo.cpp
    HEADERS     += pluginfoo.hpp \
                   pluginfoo.hpp
    DISTFILES   += pluginfoo.json
    

    The error happens if I change this:

    plugininterface.hpp

    from:

    #include "pluginmanager_global.hpp"

    to:

    #include "core_global.hpp"

    debug\moc_abstractplugin.cpp:56: warning: C4273: 'AbstractPlugin::qt_static_metacall': inconsistent dll linkage

    debug\moc_abstractplugin.cpp:63: warning: C4273: 'staticMetaObject': inconsistent dll linkage

    debug\moc_abstractplugin.cpp:63: error: C2491: 'AbstractPlugin::staticMetaObject': definition of dllimport static data member not allowed

    debug\moc_abstractplugin.cpp:70: warning: C4273: 'AbstractPlugin::metaObject': inconsistent dll linkage

    debug\moc_abstractplugin.cpp:75: warning: C4273: 'AbstractPlugin::qt_metacast': inconsistent dll linkage

    debug\moc_abstractplugin.cpp:87: warning: C4273: 'AbstractPlugin::qt_metacall': inconsistent dll linkage

    Yes, I tried qmake but it doesn't work either.



  • Anyone knows how to solve this?


  • Lifetime Qt Champion

    If you want to use the same export macros everywhere you also have to modify the DEFINES everywhere.



  • @SGaist I tried what you said and it worked. But I have a question, do you think that it's right doing that way? I don't want to be repeating code as I was doing. Is there a better way or it's just fine?


  • Lifetime Qt Champion

    Having a per library global header with the export macros even if it seems redundant is cleaner.



  • @SGaist Thank you, I'll keep the original structure then.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.