[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