2016-08-24 58 views
0

我通過創建一個Qt C++插件來擴展我的應用程序的功能鏈接問題。代碼編譯和運行一直有效,但只要我使用Qt庫類,例如QString。當我向插件的類提供對宿主應用程序中定義的類的引用時,該項目不再鏈接。創建插件我遵循Qt文檔中的步驟並考慮給出的示例 - 回顯並插入&塗料。但是,這種情況並沒有涵蓋在那裏。Qt插件使用主機應用程序的類


更新

以下是錯誤:

myPlugin.obj:-1: error: LNK2019: unresolved external symbol "public: class QString __cdecl myClass::answer(void)const " ([email protected]@@[email protected]@XZ) referenced in function "public: virtual class QString __cdecl myPlugin::echo(class myClass *)" ([email protected]@@[email protected]@[email protected]@@Z)

這裏是導致它的項目:

plugtest.pro

TEMPLATE = subdirs 

SUBDIRS += \ 
    host \ 
    plugin 

host.pro

QT  += core gui 

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 

TARGET = host 
TEMPLATE = app 


SOURCES += main.cpp\ 
     MainWindow.cpp \ 
    myClass.cpp 

HEADERS += MainWindow.h \ 
    myClass.h \ 
    plugInterface.h 

FORMS += MainWindow.ui 

MainWindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 
#include <QMessageBox> 
#include <QPluginLoader> 
#include <QDir> 
#include "myClass.h" 
#include "plugInterface.h" 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private slots: 
    void on_button_clicked(); 

private: 
    bool loadPlugin(); 

    Ui::MainWindow *ui; 

    plugInterface *m_interface; 

    myClass *m_class; 
}; 

#endif // MAINWINDOW_H 

myClass.h

#ifndef MYCLASS_H 
#define MYCLASS_H 

#include <QObject> 

class myClass : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit myClass(QObject *parent = 0); 

    QString answer() const; 
    void setAnswer(const QString &str); 

private: 
    QString m_answer; 
}; 

#endif // MYCLASS_H 

plugInterface.h

#ifndef PLUGINTERFACE_H 
#define PLUGINTERFACE_H 

#include <QString> 
#include "myClass.h" 

class plugInterface 
{ 
public: 
    virtual ~plugInterface() {} 
    virtual QString echo(myClass *value) = 0; 
}; 

#define PlugInterface_iid "example.suite.app.PluginInterface" 

Q_DECLARE_INTERFACE(plugInterface, PlugInterface_iid) 

#endif // PLUGINTERFACE_H 

MainWindow.cpp

#include "MainWindow.h" 
#include "ui_MainWindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    if (!loadPlugin()) 
    { 
     QMessageBox::information(this, "Error", "Could not load the plugin"); 
    } 

    m_class = new myClass(this); 
    m_class->setAnswer("Good!"); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

bool MainWindow::loadPlugin() 
    { 
     QDir pluginsDir(qApp->applicationDirPath()); 

     if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") 
     pluginsDir.cd("plugins"); 

     foreach (QString fileName, pluginsDir.entryList(QDir::Files)) 
     { 
      QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); 
      QObject *plugin = pluginLoader.instance(); 
      if (plugin) { 
       m_interface = qobject_cast<plugInterface *>(plugin); 
       if (m_interface) 
        return true; 
      } 
     } 

     return false; 
    } 

void MainWindow::on_button_clicked() 
{ 
    ui->lineResult->setText(m_interface->echo(m_class)); 
} 

myClass.cpp

#include "myClass.h" 

myClass::myClass(QObject *parent) : QObject(parent) 
{ 

} 

QString myClass::answer() const 
{ 
    return m_answer; 
} 

void myClass::setAnswer(const QString &str) 
{ 
    m_answer = str; 
} 

plugin.pro

TEMPLATE  = lib 
    CONFIG   += plugin 
    QT    += widgets 
    INCLUDEPATH += ../host 
    HEADERS   = myPlugin.h 
    SOURCES   = myPlugin.cpp 
    TARGET   = $$qtLibraryTarget(myPlugin) 
    DESTDIR   = ../plugins 

myPlugin.h

#ifndef MYPLUGIN_H 
#define MYPLUGIN_H 

#include <QObject> 
#include "plugInterface.h" 

class myPlugin : public QObject, plugInterface 
{ 
    Q_OBJECT 
    Q_PLUGIN_METADATA(IID "example.suite.app.PluginInterface") 
    Q_INTERFACES(plugInterface) 

public: 
    QString echo(myClass *value) Q_DECL_OVERRIDE; 
}; 

#endif // MYPLUGIN_H 

myPlugin.cpp

包括 「myPlugin.h」

QString myPlugin::echo(myClass *value) 
{ 
    return value->answer(); 
} 
+0

您不覺得錯誤信息可能有關嗎? – IInspectable

+0

當然。我將用代碼和錯誤更新問題。 – scopchanov

回答

0

爲我工作的解決方案是在myClass的一部分一個庫並將其包含在插件和主機中。不過,我很好奇這是否可以在不創建圖書館的情況下完成。