如何使用另一个DLL为Qt制作第三方插件?

时间:2013-12-28 14:10:48

标签: c++ windows qt visual-c++ dll

免责声明:Linux上的一切正常。在Windows上,我最近从MinGW更改为MSVC2012,因为我无法正确阅读MP3(请参阅Make the WMF plugin compile with MinGW.

在我的项目中,我有:

  • 核心(DLL)
  • 使用Core
  • 构建的另一个DLL
  • 媒体播放器(Qt App,同时使用DLL和加载插件)

为了保持我的项目跨平台,我还将Windows特定功能(progress bar, thumbnail buttons)提取到第三方插件中。事实上,我开始编写一个插件管理器,它在运行时加载/卸载插件而无需重新启动应用程序,它运行正常。

但是由于我已经切换到MSVC,我不能再建立我的插件了。我正面临着:

  

C4273:'staticMetaObject':不一致的dll链接

我不知道如何继续......我有以下结构:

在MainProject \ Core \ Interfaces

 class MIAMCORE_LIBRARY MediaPlayerPluginInterface : public BasicPluginInterface
 {
 public:
     virtual ~MediaPlayerPluginInterface() {}

     virtual void setMediaPlayer(QWeakPointer<MediaPlayer>) = 0;

     virtual bool providesView() const = 0;

     virtual void toggleViews(QWidget *) {}
 };

在Plugin.h中

class Minimode : public QWidget, public MediaPlayerPluginInterface
{
            Q_OBJECT
            Q_PLUGIN_METADATA(IID MediaPlayerPluginInterface_iid)
            Q_INTERFACES(MediaPlayerPluginInterface)

    private:
            Ui::ConfigForm _ui;

            QWeakPointer<MediaPlayer> _mediaPlayer;
            bool _startMoving;
            QPoint _pos, _globalPos;

    public:
            explicit Minimode();

            virtual ~Minimode();
            inline virtual QString name() const { return "Minimode"; }
            inline virtual QString version() const { return "1.0"; }
            inline virtual bool providesView() const { return true; }
            virtual QWidget* configPage();
            virtual void setMediaPlayer(QWeakPointer<MediaPlayer> mediaPlayer);
            virtual void toggleViews(QWidget *view);
    protected:
            /** Redefined to be able to drag this widget on screen. */
            void mouseMoveEvent(QMouseEvent *e);

            /** Redefined to be able to drag this widget on screen. */
            void mouseReleaseEvent(QMouseEvent *e);

            void mousePressEvent(QMouseEvent *e);

    private:
            void applyColorToStandardIcon(QPushButton *button);

    };

我的Plugin.pro

QT      += widgets multimedia
TARGET   = $$qtLibraryTarget(mini-mode)
TEMPLATE = lib

MiamPlayerBuildDirectory = C:\dev\Miam-Player\build\MiamPlayer
DEFINES += MINIMODE_MIAMPLUGIN

CONFIG  += c++11
CONFIG(debug, debug|release) {
    target.path = $$MiamPlayerBuildDirectory\debug\plugins
    LIBS += -Ldebug -lMiamCore
}

INSTALLS += target

Miamcore_global.h

#ifndef MIAMCORE_GLOBAL_H
#define MIAMCORE_GLOBAL_H

#include <QtCore/QtGlobal>

#if defined(MIAMCORE_LIBRARY)
#undef MIAMCORE_LIBRARY
#define MIAMCORE_LIBRARY Q_DECL_EXPORT
#else
#define MIAMCORE_LIBRARY Q_DECL_IMPORT
#endif

#endif // MIAMCORE_GLOBAL_H

我已尝试使用宏MIAMCORE_LIBRARY以及另一个MINIMODE_PLUGIN进行各种排列,但它们都没有工作(在类和Minimode之间但未在上面显示)。我应该在* .pro文件中添加特定关键字吗?

1 个答案:

答案 0 :(得分:2)

您的宏似乎出口和导入错误。

提供的,你不需要静态构建插件,这是一个有点真正的期望,因为那些是动态库,你应该使用你的宏如下。

另请注意,您忘记包含定义导入和导出宏的全局Qt标头。

Miamcore_global.h

#ifndef MIAMCORE_GLOBAL_H
#define MIAMCORE_GLOBAL_H

#include <QtCore/qglobal.h>

#ifdef MINIMODE_MIAMPLUGIN
# define MIAMCORE_LIBRARY Q_DECL_EXPORT
#else
# define MIAMCORE_LIBRARY Q_DECL_IMPORT
#endif

#endif // MIAMCORE_GLOBAL_H

然后,您需要在项目文件中指定以下定义:

YourPlugin.pro

...
DEFINES += MINIMODE_MIAMPLUGIN
...

这个设计在我们的插件架构中运行良好,Qt 4以及Windows和Unix上的Qt 5。

导入的东西是Windows。如果没有这个,它在Linux上会很好,但是对于Windows,你需要确保在构建插件时导出插件,但在实际使用它时导入。

这就是为什么你需要将所需的指定传递给项目文件,即该构建时间,将其导出。一旦您的用户将使用该插件,此定义将不再存在,然后将导入。