undefined reference to `typeinfo for ...'



  • Ich nutze Plugins zur Darstellung verschiedener Modalitäten von Daten (Video, 3D, Sound, ...). Die Plugins sind als Factory realisiert und funktionieren im Program (dh. die Stellen die Daten korrekt dar, die Buttons funktionieren usw.). Jeder von dem Plugin instantiierter "Wrapper" gibt sein display() an ein QMdiSubWindow und seine buttons() an eine QTabBar weiter.

    Ich versuche an einer neuen Stelle nun aus dem MDISubwindow das QWidget (==wrapperklasse) per dynamic_cast<KonkreterWrapper*>(QWidget*) auf den korrekten Wrapper zurück zu casten (auch per qobject_cast<.>(.) versucht). Bei beiden Cast erhalte ich Fehler (siehe Kommentar im Code)

    // QMdiArea *  mdiArea;   // holds the QMdiSubWindows which have a PluginWrapper as QWidget
    
        foreach (QMdiSubWindow * oneSubWin, mdiArea->subWindowList())
        {
            // get the widget from the subwindow
            QWidget * wid = oneSubWin->widget();
    
            // cast it into fitting modality
            AnnotationWrap  * an_wrap1 = 0, * an_wrap2 = 0;
    
            an_wrap1 = dynamic_cast<AnnotationWrap*>(wid); // undefined reference to 'typeinfo for AnnotationWrap'
            an_wrap2 = qobject_cast<AnnotationWrap*>(wid); // undefined reference to 'AnnotationWrap::staticMetaObject'
    
            if (an_wrap1) qDebug("dynamic_cast worked");
            if (an_wrap2) qDebug("dqobject_cast worked");
        }
    

    Google informierte mich über den dynamic_cast - Fehler: das passiert wenn man virtual deklarierte Methoden in der Basisklasse mit ; abschließt statt ein leeren Rumpf ('{ }') dran zu hängen. Mein WrapperInterface hat aber nur pure virual Methoden. Das einzige nicht pure virtual deklarierte ist der destructor und der hat einen leeren Rumpf.

    Was mach ich falsch?

    gekürzter Code für PluginInterface, ein Beispiel-Plugin und den exemplarischen Wrapper:

    factoryinterface.h

    #ifndef FACTORYINTERFACE_H
    #define FACTORYINTERFACE_H
    
    #include <QtCore/QString>
    #include <QtGui/QWidget>
    #include "data_classes/modalitybase.h"
    
    class FactoryInterface
    {
    public:
        virtual ~FactoryInterface() {}
    
        // unique id - no other plugin should have this id
        virtual QString id() const = 0;
    
        // file filter string i.e. "*.c3d *.txt *.csv"
        virtual QString fileFilter() const = 0;
    
        // factory method
        virtual QWidget * createPlugin(bool clicked, ModalityBase * mod) = 0;
    
    };
    
    Q_DECLARE_INTERFACE(FactoryInterface,
                        "padreigh.FactInterface/1.0");
    
    #endif // FACTORYINTERFACE_H
    

    Beispiel-Plugin:

    annottxtplugin.h

    // .h
    #ifndef ANNOTTEXTPLUGIN_H
    #define ANNOTTEXTPLUGIN_H
    
    #include <QtCore/QObject>
    #include "factoryinterface.h"
    #include "data_classes/modalitybase.h"
    
    #include <QtCore/QString>
    #include <QtCore/QPair>
    #include <QtCore/QMap>
    
    class AnnotationTxtPlugin : public QObject, FactoryInterface
    {
        Q_OBJECT
        Q_INTERFACES(FactoryInterface)
    
    public:
        static const QString magicID;
    
        inline QString id() const             { return magicID; }
    
        inline QString fileFilter() const     { return QString("*.annottxt"); }
    
    public slots:
        QWidget * createPlugin(bool,ModalityBase*);
    };
    #endif // ANNOTTEXTPLUGIN_H
    

    annottxtplugin.cpp

    .cpp
    #include <QtGui>
    
    #include "annottxtplugin.h"
    #include "annotationwrap.h"
    #include "data_classes/modalities/modalityannotationtxt.h"
    
    const QString AnnotationTxtPlugin::magicID = "AnnotationTxtPlugin/1.0";
    
    QWidget * AnnotationTxtPlugin::createPlugin(bool clicked, ModalityBase * mod)
    {
        if (clicked)
        {
            return new AnnotationWrap(static_cast<ModalityAnnotationTxt*>(mod),0);
        }
        return 0;
    }
    
    Q_EXPORT_PLUGIN2(annottxtplugin, AnnotationTxtPlugin);
    

    WrapperWidget:

    wrapperinterface.h

    class QWidget;
    
    // each wrapper MUST implement the methods defined here-in.
    // - display() is a QWidget which will be displayed inside a QMdiSubWindow
    // - buttons() is a QWidget which will be displayed inside a QTabBar
    // - exportData() is called to export the visualized data
    // - setupDisplay() and setupButtons() MUST be called in the constructor to setup the corresponding widgets.
    
    class WrapperInterface 
    {
    public:
        virtual ~WrapperInterface() {}
    
        virtual QWidget * display() const = 0;
        virtual QWidget * buttons() const = 0;
    
    protected: // methods
        virtual void setupDisplay() = 0;
        virtual void setupButtons() = 0;
        virtual void exportData() = 0;
    
    };
    

    annotationwrap.h

    #ifndef ANNOTATIONWRAP_H
    #define ANNOTATIONWRAP_H
    
    #include <QtCore/QTime>
    
    #include <QtGui/QWidget>
    #include "wrapperinterface.h"
    #include "data_classes/modalities/modalityannotationtxt.h"
    
    class QTableWidget;
    
    class AnnotationWrap : public QWidget, WrapperInterface
    {
        Q_OBJECT
    
    public:
        AnnotationWrap(ModalityAnnotationTxt *, QWidget * parent = 0);
    
        QWidget * buttons() const { return butt; }
        QWidget * display() const { return disp; }
    
        QSize minimumSize() const {return QSize(200,100);}
    
    public slots:
        void exportData();
        // some more slots
    
    signals: 
        // some signals
    
    private:
        QWidget * disp; // the display widget 
        QWidget * butt; // the button widget
        // some more members
    
        void setupDisplay();
        void setupButtons();
    
    private slots:
        // some private slots
    };
    
    #endif // ANNOTATIONWRAP_H
    

    annotationwrap.cpp

    #include "annotationwrap.h"
    
    #include <QtGui/QInputDialog>
    #include <QtGui/QLineEdit>
    #include <QtGui/QRegExpValidator>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QPushButton>
    #include <QtGui/QTableWidget>
    #include <QtGui/QTableWidgetItem>
    
    AnnotationWrap::AnnotationWrap(ModalityAnnotationTxt * mod, QWidget * parent)
        : QWidget(parent), m_mod(mod), table(0), disp(0), butt(0)
    {
        // parses the data from file on harddisc, 
        // data is accessible through m_mod's methods
        m_mod->parseAll(); 
    
        setupDisplay(); // setup disp;
        setupButtons(); // setup butt;
    
        QHBoxLayout * lay = new QHBoxLayout;
        lay->addWidget(disp);
        setLayout(lay);
    
        // some more QWidget() method calls 
    }
    
    void AnnotationWrap::setupDisplay()
    {
        qDebug() << "AnnotationWrap::setupDisplay()";
    
        disp = new QTableWidget();
    
        // code that fills the TableWidget with the data gathered by calling m_mods's methods
    }
    
    void AnnotationWrap::setupButtons()
    {
        qDebug() << "AnnotationWrap::setupButtons()";
    
        butt = new QWidget;
    
        // code that puts some buttons into 'butt' and connects them to slots that modify the data or visulisation
    }
    
    void AnnotationWrap::exportData()
    {
        qDebug() << "AnnotationWrap::exportData()";
    }
    


  • nevermind... ich hab die benötigten Informationen als poperty an das QMdiSubWindow gehängt ...



  • Hi,
    ich habe gerade einen ähnlichen Fehler. Wenn du dich noch an deine Lösung erinnern kannst (ist ja nu schon ne Weile her), würdest du mir diese in etwas detaillierter Form beschreiben. Ich weiß nicht, wie ich raus finde, welche Informationen in den Klassen fehlen.



  • Die Lösung findet sich natürlich immer sofort nachdem man in einem Forum dazu eine Frage gestellt hat.
    Mein Fehler war doch ein völlig anderer, bei mir lag es daran, dass ich das Q_OBJECT-Makro inkludiert habe. Ich kann nicht sagen warum, aber durch auskommentieren der Zeile war mein Problem gelöst.


Anmelden zum Antworten