C++ 创建Qt插件并使用非虚拟函数
首先,我使用VS2008和Qt4.7.0的动态构建 接口h: 我有一个和类,它实现了这个接口: myplugin.h 所以,当我在其他项目(MySpecialPlugin)中使用这个插件时,它将被编译为动态链接库(实际上也是一个插件接口实现),我不能调用它C++ 创建Qt插件并使用非虚拟函数,c++,visual-studio-2008,qt,plugins,qt4,C++,Visual Studio 2008,Qt,Plugins,Qt4,首先,我使用VS2008和Qt4.7.0的动态构建 接口h: 我有一个和类,它实现了这个接口: myplugin.h 所以,当我在其他项目(MySpecialPlugin)中使用这个插件时,它将被编译为动态链接库(实际上也是一个插件接口实现),我不能调用它 MyPlugin::goo() MySpecialPlugin的“MyPlugin.h”标题可见。Ms VS2008成功编译了该项目。但我在链接步骤LNK2001上有错误,未定义的引用。但是当更改静态void goo()时到虚拟void go
MyPlugin::goo()代码>
MySpecialPlugin的“MyPlugin.h”标题可见。Ms VS2008成功编译了该项目。但我在链接步骤LNK2001上有错误,未定义的引用。但是当更改静态void goo()时代码>到虚拟void goo()代码>它可以工作
我正在使用Q_EXPORT_PLUGIN2宏来创建插件
我做错了什么?Qt是否对插件接口的实现设置了额外的要求
首先,当你编译“myplugin”时,你需要在class关键字之后导出你的类(在windows上,它就像\uuudeclspec(dllexport)
),当你使用它编译代码时(在本例中是MySpecialPlugin)
),你可以通过简单的定义来实现
并将MYPLUGIN\u COMPILE添加到MYPLUGIN的预处理器部分
您需要针对导出库进行链接
调用静态和“正常”方法与调用虚拟方法不同…静态和“正常”方法始终位于某个地址,您的代码需要知道它在哪里…虚拟调用“检查”类vtable在您的方法实现的地址,并“动态”获取该地址另外,win32 VC平台需要定义从dll外部“导出”(公开)以访问的内容。因此,基本上,如果您想直接从MyPlugin调用任何内容(直接调用每个非虚拟成员),则,您必须在win32 VC平台上导出它。请注意,使用MyPlugin::foo()直接调用虚拟方法将导致相同的错误如果您的类声明是这样的话?您需要链接“MySpecialPlugin”使用MyPlugin Library,为什么您没有继承MyPlugin
中的PluginInterface
和QObject
?我将MyPlugin作为依赖项添加到MySpecialPlugin项目中,并将项目参数“链接库依赖项”设置为“是”。注意:问题发生在MySpecialPlugin项目的链接步骤上,而不是UIC、MOC、预处理、编译步骤…您需要在库中导出类。我需要为Qt插件执行此操作吗?因为大多数例程将由Qt创建插件(例如函数foo())?好吧,它不会为您的MyPlugin类完成,所以在这种特殊情况下,您必须完成。还要记住,静态方法解析不同于virutal…好的,但当我尝试访问普通函数(不是虚拟的,不是静态的)时,也会发生同样的情况。我只能代表Linux平台发言,但为DLL提供入口点是由Q\u EXPORT\u PLUGIN2
处理的,不需要其他任何东西。Q\u EXPORT\u PLUGIN2只导出qt\u plugin\u查询\u验证\u数据qt\u plugin\u实例函数,因此您只能使用“接口”方法,而不能使用特定于类的成员
class PluginInterface
{
public:
virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(PluginInterface, MY_PLUGIN_VERSION)
class MyPlugin: public QObject, public PluginInterface
{
public:
Q_OBJECT
Q_INTERFACES(PluginInterface)
virtual void foo(); // this functions is implemented in cpp file.
static QString goo(); // this function is also implemented in cpp file.
};
#ifdef _WIN32
#ifdef MYPLUGIN_COMPILE
#define MYPLUGIN_EXPORT __declspec(dllexport)
#else
#define MYPLUGIN_EXPORT __declspec(dllimport)
#endif
#else
#define MYPLUGIN_EXPORT
#endif
class MYPLUGIN_EXPORT MyPlugin
{
// implementation
};