首先,我使用VS 2008和Qt 4.7.0的动态构建。
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.
};
所以当我在其他项目(MySpecialPlugin)中使用这个插件时,它将被编译为动态链接库(实际上也是一个插件接口实现)我无法调用
MyPlugin::goo();
MySpecialPlugin可以看到“MyPlugin.h”的标题。并且VS2008女士成功编译了该项目。但我在链接步骤LNK2001,未定义的引用上有错误。但是,当将static void goo();
更改为virtual void goo();
时,它可以正常工作。
我正在使用Q_EXPORT_PLUGIN2宏来创建插件。
我做错了什么? Qt是否对插件接口的实现设置了额外的要求?
答案 0 :(得分:1)
首先,您需要导出您的类(在Windows上,在编译“myplugin”之后,在类关键字之后使用__declspec(dllexport)
,然后使用它编译代码时使用__declspec(dllimport)
(在这种情况下) MySpecialPlugin)。你可以通过简单的定义来实现它。read more
#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
};
将MYPLUGIN_COMPILE添加到MyPlugin的预处理器部分
您需要链接导出库
调用静态和“普通”方法不同于调用虚方法...静态和“普通”方法总是在某个地址,你的代码需要知道它在哪里...虚拟调用“检查”类vtable在什么地址您的方法有实现,并从该表“动态”获取该地址。另外win32 VC平台需要定义某些东西被“导出”(暴露)以便从dll外部访问。所以基本上如果你想直接从MyPlugin调用任何东西(非虚拟的每个成员都直接调用),你必须在win32 VC平台上导出它。请注意,使用MyPlugin :: foo()直接调用虚方法将导致相同的错误