Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

MSVC 2019: DLLImport static data member not allowed



  • I was developing my Qt C++ main application and my plugins 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.
    The main 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
    ...
    

  • Qt Champions 2017

    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_application

    And now I saw this Qt 5.15.0 little explanation here:
    https://doc.qt.io/qt-5/sharedlibrary.html

    Like 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 of signals 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!


  • Qt Champions 2019

    @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_application

    This 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 and signals and slots from the Plugin_API class (interface)
    • create a new class (Base_Plugin class)
    • In this Base_Plugin add all signals 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


  • Qt Champions 2019

    @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 from QObject, how can I use signals and slots between my main app and a plugin?


  • Qt Champions 2019

    @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.


Log in to reply