[GELÖST] 'undefined reference to' auf eigene definierte Funktion



  • Hallo Leute,

    ich versuche gerade eine "Bibliothek" in C zu schreiben und will dafür ein in Qt/C++ programmiertes FrontEnd zum testen verwenden.

    Das Make gibt folgendes Problem zurück:

    gcc -c -pipe -O2 -Wall -W -D_REENTRANT -std=c99 -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o picoCommIntfOnboard.o picoCommIntfOnboard.c
    g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o datathread.o datathread.cpp
    In file included from datathread.cpp:2:0:
    picoCommIntfOnboard.h:108:0: Warnung: »NULL« redefiniert [standardmäßig aktiviert]
    /usr/lib/gcc/i686-linux-gnu/4.6.1/include/stddef.h:399:0: Anmerkung: dies ist die Stelle der vorherigen Definition
    datathread.cpp: In Funktion »void transmit(unsigned char)«:
    datathread.cpp:48:21: Warnung: Der Rückgabewert von »ssize_t write(int, const void*, size_t)«, der mit dem Attribut warn_unused_result deklariert wurde, wird ignoriert [-Wunused-result]
    g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
    main.cpp: In Funktion »int main(int, char**)«:
    main.cpp:8:14: Warnung: Variable »thread« wird nicht verwendet [-Wunused-variable]
    /usr/bin/moc-qt4 -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. datathread.h -o moc_datathread.cpp
    g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o moc_datathread.o moc_datathread.cpp
    g++ -Wl,-O1 -o pci_onboard_qt picoCommIntfOnboard.o datathread.o main.o moc_datathread.o    -L/usr/lib/i386-linux-gnu -lQtGui -lQtCore -lpthread 
    datathread.o: In function `DataThread::DataThread()':
    datathread.cpp:(.text+0x95): undefined reference to `pciInit()'
    datathread.cpp:(.text+0xc8): undefined reference to `pciPublishVariableInt(void*, unsigned char, unsigned short, char*, char*, char*)'
    datathread.cpp:(.text+0xfb): undefined reference to `pciPublishVariableInt(void*, unsigned char, unsigned short, char*, char*, char*)'
    datathread.cpp:(.text+0x12e): undefined reference to `pciPublishVariableInt(void*, unsigned char, unsigned short, char*, char*, char*)'
    datathread.cpp:(.text+0x13a): undefined reference to `pciSetStartTxCallback(void (*)(unsigned char))'
    datathread.cpp:(.text+0x141): undefined reference to `pciEngine()'
    collect2: ld gab 1 als Ende-Status zurück
    make: *** [pci_onboard_qt] Fehler 1
    

    die ganzen Funktionen sind allerdings alle in picoCommIntfOnboard.c bzw. picoCommIntfOnboard.h definiert und benötigen keinerlei Abhängigkeiten.

    Liegt das irgendwie daran, dass ich c und c++ files zusammen kompiliere? Würde es mein problem lösen, wenn ich zuerst aus der picoCommIntfOnboard eine shared library erstelle und dann in meinem Programm einbinde? Oder kann ich doch irgendwie beide Datein miteinander kompilieren?

    In der Header der C-Datei sind auch alle Funktionen deklariert, die in der C-Datei beschrieben werden. Die c-File spuckt allerdings bei dem Versuch, es mit g++ zu kompilieren, einen Fehler aus (zeiger von void* auf unsigend short* geht nicht oder so).

    Irgendeine Idee, was ich falsch mache?

    Schöne Grüße



  • Serenity schrieb:

    Liegt das irgendwie daran, dass ich c und c++ files zusammen kompiliere?

    Genau das. Du hast wahrscheinlich deine C-Funktionen im C++-Code nicht mit extern "C" deklariert. Wenn Du die Funktionen im Header deklarierst solltest Du die Funktionsdeklarationen im Header so einrahmen:

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    /* hier die Funktionen deklarieren */
    #ifdef __cplusplus
    }
    #endif
    

    Dadurch sagst Du dem C++-Compiler, dass das C-Funktionen sind und diese nicht am name-mangling teil nehmen.

    In C++ ist es erlaubt, mehrere Funktionen mit dem gleichen Namen zu deklarieren, wenn sie sich durch die Parameterliste unterscheiden. Das löst der C++-Compiler dadurch, dass er die Parameterliste im Funktionsnamen kodiert, also die externen Funktionsnamen verändert. Damit kann allerdings der C-Compiler nichts anfangen. Dadurch findet der Linker die Funktionen gar nicht.

    Du kannst das auch daran erkennen, dass der Linker die Funktionen mit seinen Parametern auflistet. Der Linker würde keine Parameter kennnen, wären sie nicht im Funktionsnamen kodiert.



  • Vielen herzlichen Dank 🙂
    Genau das war das Problem 🙂


Log in to reply