Qt: undefined reference to...



  • Hi,

    Edit: BITTE DIE ERGÄNZUNGEN LESEN. In meinem dritten Post verweise ich auf eine bestimmte Stelle, die Probleme verursacht (soweit bin ich jetzt), d.h. ihr müsst euch nur einen kleinen Teil angucken, wenn ihr unten anfangt.
    Danke.

    ich versuche z.Z. verzweifelt ein Qt 4.2.3 Projekt (bzw. einen Vorab-Test) zu erstellen.

    Es klappt sowohl mit Code::Blocks (mit MinGW), als auch mit der "Qt Command Prompt" (wieder MinGW) nicht.
    (Ich hab zusätzlich den Qt Designer verwendet).

    Bei Code::Blocks habe ich es so eingestellt, dass ein moc-File erzeugt wird.
    Über die Command Prompt klappt das auch (qmake -project, qmake projekt.pro).

    Erst beim make bzw Linken stürzt er mit mehreren undefined references ab:

    Code::Blocks schrieb:

    C:\Dokumente und Einstellungen\Ruediger1\Desktop\Dokumente\Programmierung\Nullstellen\release\moc_SummandDialog.cpp:66: undefined reference to SummandDialog::on\_lineEditAnzahlSummanden_textChanged()' C:\\Dokumente und Einstellungen\\Ruediger1\\Desktop\\Dokumente\\Programmierung\\Nullstellen\\release\\moc\_SummandMain.cpp:66: undefined reference toSummandMain::on_lineEdit_alltextsChanged()'
    C:\Dokumente und Einstellungen\Ruediger1\Desktop\Dokumente\Programmierung\Nullstellen\release\moc_SummandMain.cpp:: undefined reference to Ui::SummandMain::~SummandMain()' obj\\Debug\\release\\moc\_SummandMain.o(.text$\_ZN11SummandMainD0Ev[SummandMain::~SummandMain()]+0x67):C:\\Dokumente und Einstellungen\\Ruediger1\\Desktop\\Dokumente\\Programmierung\\Nullstellen\\release\\moc_SummandMain.cpp:: undefined reference toUi::SummandMain::~SummandMain()'
    C:\Dokumente und Einstellungen\Ruediger1\Desktop\Dokumente\Programmierung\Nullstellen\main.cpp:12: undefined reference to SummandMain::SummandMain(QWidget*)' obj\\Debug\\main.o(.text+0x20b):C:\\Dokumente und Einstellungen\\Ruediger1\\Desktop\\Dokumente\\Programmierung\\Nullstellen\\main.cpp:13: undefined reference toSummandDialog::SummandDialog(QWidget*)'
    :: === Build finished: 6 errors, 0 warnings ===

    Bzw in der Command Prompt:

    MinGW über Qt Command Prompt schrieb:

    ]release\SummandMain.o(.text+0x2a1):SummandMain.cpp: undefined reference to Ui:: SummandMain::~SummandMain()' release\\SummandMain.o(.text+0x601):SummandMain.cpp: undefined reference toUi::
    SummandMain::~SummandMain()'
    release\moc_SummandMain.o(.text\_ZN11SummandMainD1Ev[SummandMain::~SummandMain() ]+0x63):moc_SummandMain.cpp: undefined reference to `Ui::SummandMain::~SummandMa in()' release\\moc\_SummandMain.o(.text_ZN11SummandMainD0Ev[SummandMain::~SummandMain()
    ]+0x63):moc_SummandMain.cpp: undefined reference to Ui::SummandMain::~SummandMa in()' collect2: ld returned 1 exit status mingw32-make[1]: *** [release\\Nullstellen.exe] Error 1 mingw32-make[1]: Leaving directoryC:/Dokumente und Einstellungen/Ruediger1/Des
    ktop/Dokumente/Programmierung/Nullstellen'
    mingw32-make: *** [release] Error 2

    C:\Dokumente und Einstellungen\Ruediger1\Desktop\Dokumente\Programmierung\Nullst
    ellen>

    Zu den Fehler bei Code::Blocks lässt sich folgendes sagen:
    Zweimal führt ein Aufruf aus der moc-Datein zu einem Fehler (beide Slots),
    zweimal führt ein unbestimmter Aufruf zu einem Fehler bei den Destruktoren,
    zweimal führt der Aufruf der Konstruktoren (aus der main.cpp) zu einem Fehler.

    Ich steig da echt nicht mehr durch, ich hab schon an allen mögliche Stellen Destruktoren hinugefügt (ob virtual oder nicht), habs mit und ohne IDE versucht...
    Außerdem lässt sich ein vergleichbares Projekt problemlos kompilieren.

    Ich habe leider keine Ahnung, wo der Fehler stecken könnte, deswegen muss ich den Quellcode ganz posten:

    //main.cpp
    #include <QApplication>
    #include <QFont>
    #include <QPushButton>
    
    #include "SummandDialog.h"
    #include "SummandMain.h"
    
    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
    
        SummandMain* Main = new SummandMain;
        SummandDialog* Dialog = new SummandDialog(Main);
    
        Dialog->show();
    
        return app.exec();
    }
    
    //SummandDialog.h
    
    #ifndef _SUMMANDDIALOG_H_
    #define _SUMMANDDIALOG_H_
    
    #include <QDialog>
    
    #include "ui_SummandenDialog.h"
    
    class SummandDialog : public QDialog, public Ui::SummandDialog
    {
        Q_OBJECT
    
        int summanden;
    
        public:
        SummandDialog(QWidget *parent);
    
        private slots:
        void on_lineEditAnzahlSummanden_textChanged();
    };
    
    #endif
    
    // SummandDialog.cpp
    
    #include <QtGui>
    
    #include "SummandDialog.h"
    
    SummandDialog::SummandDialog(QWidget *parent)
        : QDialog(parent)
    {
        Ui::SummandDialog::setupUi(this);
    
        QRegExp regExp("[1-9][0-9]{0,9}");        // erlaubt: 1-9 gefolgt von 0 bis 9 Ziffern
        lineEditAnzahlSummanden->setValidator(new QRegExpValidator(regExp, this));
    
        connect(okDialog, SIGNAL(clicked()), this, SLOT(accept()));
    }
    
    void SummandDialog::on_lineEditAnzahlSummanden_textChanged()
    {
        okDialog->setEnabled(lineEditAnzahlSummanden->hasAcceptableInput());
    }
    
    // SummandMain.h
    
    #ifndef _SUMMANDMAIN_
    #define _SUMMANDMAIN_
    
    #include <QDialog>
    
    #include "ui_SummandMain.h"
    
    class SummandMain : public QDialog, public Ui::SummandMain
    {
        Q_OBJECT
    
        public:
    
        SummandMain(QWidget *parent = 0);
    
        private slots:
    
        void on_lineEdit_alltextsChanged();
    };
    
    #endif
    
    // SummandMain.cpp
    
    #include <QtGui>
    
    #include "SummandMain.h"
    
    SummandMain::SummandMain(QWidget *parent)
        : QDialog(parent)
    {
        Ui::SummandMain::setupUi(this);
    
        QRegExp regExp("[1-9][0-9]{0,9}");        // erlaubt: 1-9 gefolgt von 0 bis 9 Ziffern
        lineEditKoeffizient->setValidator(new QRegExpValidator(regExp, this));
        lineEditXSummand->setValidator(new QRegExpValidator(regExp, this));
        lineEditExponent->setValidator(new QRegExpValidator(regExp, this));
    
        connect(okMain, SIGNAL(clicked()), this, SLOT(accept()));              // ERSTMAL NICHTS --> FOLGT
    }
    
    void SummandMain::on_lineEdit_alltextsChanged()
    {
        okMain->setEnabled(lineEditKoeffizient->hasAcceptableInput());
    }
    

    Und jetzt noch die passenden Files vom Qt-Desinger:

    /********************************************************************************
    ** Form generated from reading ui file 'SummandMain.ui'
    **
    ** Created: Mon 21. May 16:55:36 2007
    **      by: Qt User Interface Compiler version 4.2.3
    **
    ** WARNING! All changes made in this file will be lost when recompiling ui file!
    ********************************************************************************/
    
    #ifndef UI_SUMMANDMAIN_H
    #define UI_SUMMANDMAIN_H
    
    #include <QtCore/QVariant>
    #include <QtGui/QAction>
    #include <QtGui/QApplication>
    #include <QtGui/QButtonGroup>
    #include <QtGui/QGridLayout>
    #include <QtGui/QGroupBox>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QLabel>
    #include <QtGui/QLineEdit>
    #include <QtGui/QPushButton>
    #include <QtGui/QSpacerItem>
    #include <QtGui/QWidget>
    
    class Ui_SummandMain
    {
    public:
        QGridLayout *gridLayout;
        QHBoxLayout *hboxLayout;
        QSpacerItem *spacerItem;
        QPushButton *okMain;
        QSpacerItem *spacerItem1;
        QSpacerItem *spacerItem2;
        QGroupBox *groupBox;
        QGridLayout *gridLayout1;
        QLineEdit *lineEditExponent;
        QSpacerItem *spacerItem3;
        QHBoxLayout *hboxLayout1;
        QLineEdit *lineEditKoeffizient;
        QLabel *x;
        QLineEdit *lineEditXSummand;
        QLabel *labelKlammerZu;
        QSpacerItem *spacerItem4;
    
        void setupUi(QWidget *SummandMain)
        {
        SummandMain->setObjectName(QString::fromUtf8("SummandMain"));
        gridLayout = new QGridLayout(SummandMain);
        gridLayout->setSpacing(6);
        gridLayout->setMargin(9);
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
        hboxLayout = new QHBoxLayout();
        hboxLayout->setSpacing(6);
        hboxLayout->setMargin(0);
        hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
        spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        hboxLayout->addItem(spacerItem);
    
        okMain = new QPushButton(SummandMain);
        okMain->setObjectName(QString::fromUtf8("okMain"));
    
        hboxLayout->addWidget(okMain);
    
        spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        hboxLayout->addItem(spacerItem1);
    
        gridLayout->addLayout(hboxLayout, 2, 0, 1, 1);
    
        spacerItem2 = new QSpacerItem(20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding);
    
        gridLayout->addItem(spacerItem2, 1, 0, 1, 1);
    
        groupBox = new QGroupBox(SummandMain);
        groupBox->setObjectName(QString::fromUtf8("groupBox"));
        gridLayout1 = new QGridLayout(groupBox);
        gridLayout1->setSpacing(6);
        gridLayout1->setMargin(9);
        gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
        lineEditExponent = new QLineEdit(groupBox);
        lineEditExponent->setObjectName(QString::fromUtf8("lineEditExponent"));
    
        gridLayout1->addWidget(lineEditExponent, 0, 1, 1, 1);
    
        spacerItem3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        gridLayout1->addItem(spacerItem3, 0, 0, 1, 1);
    
        hboxLayout1 = new QHBoxLayout();
        hboxLayout1->setSpacing(6);
        hboxLayout1->setMargin(0);
        hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
        lineEditKoeffizient = new QLineEdit(groupBox);
        lineEditKoeffizient->setObjectName(QString::fromUtf8("lineEditKoeffizient"));
    
        hboxLayout1->addWidget(lineEditKoeffizient);
    
        x = new QLabel(groupBox);
        x->setObjectName(QString::fromUtf8("x"));
    
        hboxLayout1->addWidget(x);
    
        lineEditXSummand = new QLineEdit(groupBox);
        lineEditXSummand->setObjectName(QString::fromUtf8("lineEditXSummand"));
    
        hboxLayout1->addWidget(lineEditXSummand);
    
        labelKlammerZu = new QLabel(groupBox);
        labelKlammerZu->setObjectName(QString::fromUtf8("labelKlammerZu"));
    
        hboxLayout1->addWidget(labelKlammerZu);
    
        gridLayout1->addLayout(hboxLayout1, 1, 0, 1, 1);
    
        spacerItem4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        gridLayout1->addItem(spacerItem4, 1, 1, 1, 1);
    
        gridLayout->addWidget(groupBox, 0, 0, 1, 1);
    
        retranslateUi(SummandMain);
    
        QSize size(454, 201);
        size = size.expandedTo(SummandMain->minimumSizeHint());
        SummandMain->resize(size);
    
        QMetaObject::connectSlotsByName(SummandMain);
        } // setupUi
    
        void retranslateUi(QWidget *SummandMain)
        {
        SummandMain->setWindowTitle(QApplication::translate("SummandMain", "SummandMain", 0, QApplication::UnicodeUTF8));
        okMain->setText(QApplication::translate("SummandMain", "OK", 0, QApplication::UnicodeUTF8));
        groupBox->setTitle(QApplication::translate("SummandMain", "Summand bestimmten", 0, QApplication::UnicodeUTF8));
        x->setText(QApplication::translate("SummandMain", "( x + ", 0, QApplication::UnicodeUTF8));
        labelKlammerZu->setText(QApplication::translate("SummandMain", " ) ", 0, QApplication::UnicodeUTF8));
        Q_UNUSED(SummandMain);
        } // retranslateUi
    
        virtual ~Ui_SummandMain();
    
    };
    
    namespace Ui {
        class SummandMain: public Ui_SummandMain {public: virtual ~SummandMain();};
    } // namespace Ui
    
    #endif // UI_SUMMANDMAIN_H
    
    ********************************************************************************
    ** Form generated from reading ui file 'SummandenDialog.ui'
    **
    ** Created: Mon 21. May 16:55:36 2007
    **      by: Qt User Interface Compiler version 4.2.3
    **
    ** WARNING! All changes made in this file will be lost when recompiling ui file!
    ********************************************************************************/
    
    #ifndef UI_SUMMANDENDIALOG_H
    #define UI_SUMMANDENDIALOG_H
    
    #include <QtCore/QVariant>
    #include <QtGui/QAction>
    #include <QtGui/QApplication>
    #include <QtGui/QButtonGroup>
    #include <QtGui/QGridLayout>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QLabel>
    #include <QtGui/QLineEdit>
    #include <QtGui/QPushButton>
    #include <QtGui/QSpacerItem>
    #include <QtGui/QWidget>
    
    class Ui_SummandDialog
    {
    public:
        QGridLayout *gridLayout;
        QSpacerItem *spacerItem;
        QSpacerItem *spacerItem1;
        QPushButton *okDialog;
        QHBoxLayout *hboxLayout;
        QLabel *SummandenLabel;
        QLineEdit *lineEditAnzahlSummanden;
    
        void setupUi(QWidget *SummandDialog)
        {
        SummandDialog->setObjectName(QString::fromUtf8("SummandDialog"));
        gridLayout = new QGridLayout(SummandDialog);
        gridLayout->setSpacing(6);
        gridLayout->setMargin(9);
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
        spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        gridLayout->addItem(spacerItem, 1, 2, 1, 1);
    
        spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
        gridLayout->addItem(spacerItem1, 1, 0, 1, 1);
    
        okDialog = new QPushButton(SummandDialog);
        okDialog->setObjectName(QString::fromUtf8("okDialog"));
    
        gridLayout->addWidget(okDialog, 1, 1, 1, 1);
    
        hboxLayout = new QHBoxLayout();
        hboxLayout->setSpacing(6);
        hboxLayout->setMargin(0);
        hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
        SummandenLabel = new QLabel(SummandDialog);
        SummandenLabel->setObjectName(QString::fromUtf8("SummandenLabel"));
    
        hboxLayout->addWidget(SummandenLabel);
    
        lineEditAnzahlSummanden = new QLineEdit(SummandDialog);
        lineEditAnzahlSummanden->setObjectName(QString::fromUtf8("lineEditAnzahlSummanden"));
    
        hboxLayout->addWidget(lineEditAnzahlSummanden);
    
        gridLayout->addLayout(hboxLayout, 0, 0, 1, 3);
    
        retranslateUi(SummandDialog);
    
        QSize size(276, 101);
        size = size.expandedTo(SummandDialog->minimumSizeHint());
        SummandDialog->resize(size);
    
        QMetaObject::connectSlotsByName(SummandDialog);
        } // setupUi
    
        void retranslateUi(QWidget *SummandDialog)
        {
        SummandDialog->setWindowTitle(QApplication::translate("SummandDialog", "SummandDialog", 0, QApplication::UnicodeUTF8));
        okDialog->setText(QApplication::translate("SummandDialog", "OK", 0, QApplication::UnicodeUTF8));
        SummandenLabel->setText(QApplication::translate("SummandDialog", "Anzahl Summanden w\303\244hlen:", 0, QApplication::UnicodeUTF8));
        Q_UNUSED(SummandDialog);
        } // retranslateUi
    
        virtual ~Ui_SummandDialog() {};
    
    };
    
    namespace Ui {
        class SummandDialog: public Ui_SummandDialog {public: virtual ~SummandDialog() {};};
    } // namespace Ui
    
    #endif // UI_SUMMANDENDIALOG_H
    

    Entschuldigt bitte, dass ich so viel Quellcode poste, aber ich versuche halt schon den ganzen Tag, den Fehler zu beheben und bisher ist es mir nichtmal gelungen, ihn zu lokalisieren...



  • Ok, also zuminest die Fehler zu den Destruktoren

    C:\Dokumente und Einstellungen\Ruediger1\Desktop\Dokumente\Programmierung\Nullstellen\release\moc_SummandMain.cpp:: undefined reference to Ui::SummandMain::~SummandMain()' obj\\Debug\\release\\moc\_SummandMain.o(.text$\_ZN11SummandMainD0Ev[SummandMain::~SummandMain()]+0x67):C:\\Dokumente und Einstellungen\\Ruediger1\\Desktop\\Dokumente\\Programmierung\\Nullstellen\\release\\moc_SummandMain.cpp:: undefined reference toUi::SummandMain::~SummandMain()'

    sind jetzt weg, nachdem ich sie einfach aus den ui_*.h Dateien gelöscht habe..

    Der Rest meckert wie gehabt.



  • Hm, also jetzt habe ich in den ui_*.h Dateien die Funktion "connectSlotsByName(...)" auskommentiert und die Slots manuell verbunden.
    Und nun geht es auch 🙂

    Trotzdem meine Frage: Wie schaffe ich es, dass "connectSlotsByName(...)" funktioniert? Bei meinem anderen Projekt ging es schließlich auch...

    Edit: Auch nur MinGW über die Konsole schafft es dann, Code::Blocks schmiert weiterhin ab...


Anmelden zum Antworten