Solved MSVC 2019: DLLImport static data member not allowed
-
I was developing my Qt C++
main application
and myplugins
in a Linux Ubuntu 20.04 machine and both projects works well in this system.Now, I copied both Qt projects to my Windows 10 machine.
Themain app
works great!But the
plugin
project gives me this compile time error below:moc_plugin.cpp: 81: error: C2491: 'Plugin :: staticMetaObject': ‡ definition ‡ ‡ dllimport static data member not allowed
Besides that, I got the same warning 43 times too:
moc_plugin.cpp: 107: warning: C4273: 'Plugin :: qt_metacall': inconsistent dll link
Fiinally, I got too a lot of this warnings below (one for each plugin method):
warning: 'Plugin::myMethod' redeclared without 'dllimport' attribute: 'dllexport' attribute added
Here is my
Interface
(Plugin_API class
):#ifndef PLUGIN_QT_API_H #define PLUGIN_QT_API_H #include <QtPlugin> #include <QString> #include "third-party/highfive/H5Easy.hpp" #include "third-party/nlohmann/json.hpp" #include "message_types.h" #define API_VERSION_MAJOR 1 #define API_VERSION_MINOR 0 #define API_VERSION_FIX 0 using JSON = nlohmann::json; class Plugin_API : public QObject { Q_OBJECT private: public: QString _pluginName; QString _pluginType; QString _authorName; QString _authorEmail; QString _company; size_t _majorVersion; size_t _minorVersion; size_t _fixVersion; JSON _inputArgumentsTypes; JSON _outputArgumentsTypes; JSON* _project; QString _filename; H5Easy::File *_outputFile; bool _enableWriteResultsToFile; Plugin_API() : _majorVersion(0), _minorVersion(0), _fixVersion(0), _enableWriteResultsToFile(true) {} virtual ~Plugin_API() = default; virtual const QString getName(void) const = 0; virtual const QString getType(void) const = 0; virtual const JSON getMetadata(void) const = 0; virtual const JSON* getProject(void) const = 0; // ===== SETTER METHODS ===== // virtual void setProject(JSON* project) = 0; virtual void setPluginName(const QString& pluginName) = 0; // ===== OTHER METHODS ===== // virtual void sendStatusMsg(const QString& msg) = 0; virtual void sendWarningMsg(const QString& msg) = 0; virtual void sendErrorMsg(const QString& msg) = 0; virtual void setMetadata(void) = 0; virtual void initInputParameters(void) = 0; virtual void setInputArgumentsTypes(const JSON& input) = 0; virtual void setOutputArgumentsTypes(const JSON& output) = 0; signals: void sendMsg(QString source, MSG_TYPE msgType, QString msg); void savePluginSettings(JSON settings); }; Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin") #endif // PLUGIN_QT_API_H
Here is the
message_types.h
:#ifndef MESSAGE_TYPES_H #define MESSAGE_TYPES_H enum MSG_TYPE { ERROR_MSG = -2, WARNING_MSG = -1, STATUS_MSG = 0 }; #endif // MESSAGE_TYPES_H
Here is the
plugin_global.h
:#ifndef PLUGIN_GLOBAL_H #define PLUGIN_GLOBAL_H #include <QtCore/qglobal.h> #if defined(PLUGIN_LIBRARY) # define PLUGIN_EXPORT Q_DECL_EXPORT #else # define PLUGIN_EXPORT Q_DECL_IMPORT #endif #endif // PLUGIN_GLOBAL_H
Here is the
plugin.h
:#include <vector> #include "dialog.h" #include "plugin_global.h" #include "plugin_qt_api.h" class PLUGIN_EXPORT Plugin : public Plugin_API { Q_OBJECT Q_PLUGIN_METADATA(IID "com.rotortest.plugin") Q_INTERFACES(Plugin_API) private: Dialog _ui; public: explicit Plugin(QObject* parent = nullptr); ~Plugin(); all_methods override; public slots: void receivedUi(JSON& ui); };
How can I solve it and compile the
plugin
project on my Windows machine?My systems are:
System A (Working good!)
- Ubuntu 20.04 x64
- Qt Creator IDE 4.12.4
- Qt 5.15.0
- GCC 9.3
System B (NOT compiling the plugin project)
- Windows 10 x64
- Qt Creator IDE 4.12.4
- Qt 5.15.0
- MSVC 2019
-
Hi, it might be something missing in the .pro file for the plugin project, it should have a line like this:
... DEFINES += PLUGIN_LIBRARY ...
-
Hi, it might be something missing in the .pro file for the plugin project, it should have a line like this:
... DEFINES += PLUGIN_LIBRARY ...
-
Interfaces don't have members, and they for sure don't derive from
QObject
. There's a pretty decent example in the documentation, you should follow it. -
@hskoglund said in MSVC 2019: DLLImport static data member not allowed:
DEFINES += PLUGIN_LIBRARY
Thank you for your quick response...
First: It works and solved my error and all warnings in the MSVC compilation!But I don't get your point with this
define
line.
Why this line fixed my problem? -
While I haven't built any Qt plugins, but if they are built the same way normal .dlls are, then the error you get " ...import ... not allowed" when compiling your plugin, could be due to that missing #define.
If you look in the
plugin_global.h
file, the error maybe can occur if
#define PLUGIN_EXPORT Q_DECL_EXPORT
gets #defined rather than
#define PLUGIN_EXPORT Q_DECL_IMPORT(i..e the plugin should be exporting its functions, not importing them)
-
@kshegunov said in MSVC 2019: DLLImport static data member not allowed:
There's a pretty decent example in the documentation, you should follow it.
Thank you for your attention.
Could you please give me links about this information?I follow this Qt Wiki tutorial below:
https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_applicationAnd now I saw this Qt 5.15.0 little explanation here:
https://doc.qt.io/qt-5/sharedlibrary.htmlLike you said before, may be I'm doing something wrong and I would like to do it right!
I derived my interface from
QObject
because I saw it on a Udemy Qt online course...
I was thinking that this was "the right way" to add the same set ofsignals and slots
for all developed plugins.But I would like to do that in the best possible way.
Please @kshegunov , if is there a better way, feel free to comment about it.Thank you!
-
@hskoglund said in MSVC 2019: DLLImport static data member not allowed:
missing #define.
#ifndef PLUGIN_GLOBAL_H #define PLUGIN_GLOBAL_H #include <QtCore/qglobal.h> #if defined(PLUGIN_LIBRARY) // HERE IS WHY YOU NEED TO PASS THIS DEFINE AT COMPILATION TIME # define PLUGIN_EXPORT Q_DECL_EXPORT #else # define PLUGIN_EXPORT Q_DECL_IMPORT #endif #endif // PLUGIN_GLOBAL_H
Brilhant @hskoglund ! Thank you so much!
-
@fem_dev said in MSVC 2019: DLLImport static data member not allowed:
I follow this Qt Wiki tutorial below:
https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_applicationThis is for normal libraries, not plug-ins.
If you want to implement a plug-in why not following https://doc.qt.io/qt-5/plugins-howto.html ?
There are links to examples... -
@fem_dev said in MSVC 2019: DLLImport static data member not allowed:
But I would like to do that in the best possible way.
In this case that I want to give the same set of
signals and slots
to all my develop plugins should I:- Remove all variable members,
QObject
andsignals and slots
from thePlugin_API
class (interface) - create a new class (
Base_Plugin
class) - In this
Base_Plugin
add allsignals and slots
- In this
Base_Plugin
add all variable members that are commum to all plugins - For each
Plugin
derive like:
class PLUGIN_EXPORT Plugin : public QObject, public Base_Plugin, public Plugin_API { ... all_methods override; ... }`
Is this the right way?
@hskoglund @kshegunov @jsulm - Remove all variable members,
-
@fem_dev See "The Low-Level API: Extending Qt Applications" in the link I posted.
There is no need for two classes Base_Plugin and Plugin_API.
Implement one interface class and derive your Plugin from it and QObject as shown in the example. -
@jsulm said in MSVC 2019: DLLImport static data member not allowed:
There is no need for two classes Base_Plugin and Plugin_API.
Thank you for the informations.
Doubt:
If the interface doesn't derive fromQObject
, how can I usesignals and slots
between mymain app
and aplugin
? -
@fem_dev said in MSVC 2019: DLLImport static data member not allowed:
If the interface doesn't derive from QObject, how can I use signals and slots between my main app and a plugin?
If the interface class does not derive from QObject it can still create and return instances of QObject derived classes.