Solved 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
withcore_global.hpp
with the same content ofpluginmanager_global.hpp
and I wanted to removepluginmanager_global.hpp
then I included on thepro
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?
-
@Defohin Did you run qmake and did you a complete rebuild after these changes?
-
Yes, I did and nothing... The error continues.
-
Hi,
Did you properly define
MYPROJECT_LIBRARY
when building the library and not when using it ? -
@SGaist Yes,
DEFINES += CORE_LIBRARY
in thecore
library andDEFINES += PLUGINMANAGER_LIBRARY
in thepluginmanager
. -
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 thecore_global.hpp
, tried to include that header on thepluginmanager
and I get the errors... -core_global.hpp
has the same content aspluginmanager_global.hpp
but it only works with it, not withcore_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
causeAbstractPlugin
does that already and if I make a plugin inherent fromQObject
as well the compiler throws me a warning saying that the two of them is inheriting the same class. -
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
andPLUGINMANAGER_LIBRARY
, and they are both defined on their relatedpro
files. I just can't use the header from one library on the other one and these errors happen. -
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
TEMPLATE = subdirs SUBDIRS = core \ pluginmanager \ plugins \ myproject CONFIG += ordered
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(); }
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
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
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
{}
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?
-
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?
-
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.
-
This seems to be the top search result for this warning so I'd like to add a note relating to a case I've found.
I've cloned and built the open-source project "qModMaster", and this warning comes up a lot.
What appears to have happened is that the library "libmodbus" is statically linked into qModMaster, but the libmodbus source assumes it will be implemented as a DLL, so the warnings come up every time it attempts to import/export a function. I believe the inconsistency is that it has both a definition for the function and a directive to import the function.
. #if defined(_MSC_VER)
. # if defined(DLLBUILD)
. /* define DLLBUILD when building the DLL */
. # define MODBUS_API __declspec(dllexport)
. # else
. # define MODBUS_API __declspec(dllimport)
. # endifIn this case the library has been modified after adding it to the project, it isn't a clone so in the short term it is easiest to just define MODBUS_API as nothing.
-
@Oliver-Broad said in Inconsistent dll linkage:
qModMaster
Hi and welcome to devnet,
Which version of qModMaster are you talking about ?
From a quick search, the only thing I have found is that libmodbus is a C library so it is not concerned by these export/import considerations and qModMaster does not use it as a library but compiles the sources it uses directly into the executable.