如何使用另一个 DLL 为 Qt 制作第三方插件?
Posted
技术标签:
【中文标题】如何使用另一个 DLL 为 Qt 制作第三方插件?【英文标题】:How to make a third party plugin for Qt using another DLL? 【发布时间】:2013-12-28 14:10:47 【问题描述】:免责声明:在 Linux 上一切正常。在 Windows 上,我最近从 MinGW 更改为 MSVC2012,因为我无法正确读取 MP3(请参阅Make the WMF plugin compile with MinGW.)
在我的项目中,我有:
核心 (DLL) 另一个使用 Core 构建的 DLL 媒体播放器(Qt 应用,同时使用 DLL 和加载插件)为了让我的项目跨平台,我还将 Windows 特定功能 (progress bar, thumbnail buttons) 提取到了第 3 方插件中。事实上,我正在开始编写一个插件管理器,它在运行时加载/卸载插件,无需重新启动应用程序,它工作正常。
但自从我切换到 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);
;
我的插件.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 文件中添加特定的关键字吗?
【问题讨论】:
显示“MIAMCORE_LIBRARY”的定义,同时修正你的代码格式... 【参考方案1】:您的宏似乎对导出和导入有误。
前提是,您不需要为插件进行静态构建,这是一个有点现实的期望,因为它们是动态库,您应该使用如下所示的宏。
还请注意,您忘记包含定义导入和导出宏的全局 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,你需要确保在构建它时导出插件,但在实际使用它时导入。
这就是为什么您需要将所需的名称传递给此构建时导出的项目文件。一旦,您的用户将使用该插件,此定义将不再存在,然后将被导入。
【讨论】:
以上是关于如何使用另一个 DLL 为 Qt 制作第三方插件?的主要内容,如果未能解决你的问题,请参考以下文章
使用 QT Creator,如何制作不需要在目标平台上安装 .dll 的 Windows 可执行文件? [复制]