未从Qt dll检索的对象成员

时间:2018-01-25 14:14:56

标签: c++ qt

我尝试动态地从Qt共享库到Qt应用程序获取QObject子类对象。

我尝试应用之前关于此主题的答案:QLibrary - import a class

这是我的常用界面tabappinterface.h:

#ifndef TABAPP_H
#define TABAPP_H

#include <QObject>
#include <QWidget>

class TabAppInterface : public QObject
{
    Q_OBJECT
public:
    virtual ~TabAppInterface()
    {
    }
    QWidget *app;
    QString title;
};

#endif // TABAPP_H

我的类dll-side mytabapp.h:

#ifndef MYTAB_H
#define MYTAB_H

#include "tabapp_global.h"
#include "tabappinterface.h"

class MYTABSHARED_EXPORT MyTabApp: public TabAppInterface
{
public:
    MyTabApp();
    virtual ~MyTabApp();
    QWidget *app;
    QString title;
};

extern "C" MYTABSHARED_EXPORT TabAppInterface *getTabApp();

及其实现mytabapp.cpp:

#include "mytabapp.h"

MyTabApp::MyTabApp()
{
    app = new AppWidget();
    title = QStringLiteral("My Tab App");
}

MyTabApp::~MyTabApp()
{

}

TabAppInterface *getTabApp()
{
    return new MyTabApp();
}

我的应用程序端实现:

void ContainerMainWindow::loadLibraries()
{
    QLibrary myLib("mytabapp.dll");
    if(myLib.isLoaded())
    {
        qDebug() << "Loaded!";
    }
    typedef TabAppInterface *(*tabAppGetProt)();
    auto tabAppGetter = (tabAppGetProt) myLib.resolve("getTabApp");
    if(tabAppGetter)
    {
        auto *tabApp = tabAppGetter(); // not null
        qDebug() << tabApp->title; // print empty string
        qDebug() << (QWidget *)(tabApp->app); // SEGFAULT
    }
}

如最后几行中的注释中所述,虽然tabApp不为null,但未检索到对象成员。

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

您正在访问没有人初始化的基类变量(字段)titleapp。这些变量根本不是虚拟的,因此派生类中的变量只隐藏基类中的变量。作为解决方案,您可以在基类中将它们声明为受保护,并将它们封装在getter和setter中。

这样,您的基类就像:

class TabAppInterface : public QObject
{
    Q_OBJECT
public:
    virtual ~TabAppInterface(){}

    QWidget *getApp() const { return app; }
    void setApp(QWidget *value) { app = value; }

    QString getTitle() const { return title; }
    void setTitle(const QString &value) { title = value; }

protected:
    QWidget *app;
    QString title;
};

,派生类就像:

class MYTABSHARED_EXPORT MyTabApp: public TabAppInterface
{
public:
    MyTabApp();
    virtual ~MyTabApp();
};

你仍然可以直接访问派生类中的变量(即在构造函数中初始化它们),并通过外部的getters / setters方法:

    auto *tabApp = tabAppGetter();
    qDebug() << tabApp->getTitle();
    qDebug() << tabApp->getApp();