Ich richte ein C ++ - Projekt unter Ubuntu x64 mit Eclipse-CDT ein. Ich mache im Grunde genommen eine Hallo-Welt und verbinde mich mit einer kommerziellen Bibliothek von Drittanbietern.
Ich habe die Header-Dateien eingefügt, die mit ihren Bibliotheken verknüpft sind, aber ich erhalte immer noch Linker-Fehler. Gibt es hier andere mögliche Probleme als die offensichtlichen (z. B. bin ich zu 99% sicher, dass ich auf die richtige Bibliothek verlinke).
- Gibt es eine Möglichkeit zu bestätigen, dass die statischen Bibliotheken, mit denen ich verknüpfe, 64-Bit sind?
- Gibt es eine Möglichkeit zu bestätigen, dass die Bibliothek die Klasse (und Methoden) hat, die ich erwarte?
Eclipse sagt:
Gebäudeziel: LinkProblem Aufrufen: GCC C ++ Linker g ++ -L / home / notroot / workspace / somelib-3 / somelib / target / bin -o "LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3 ./src/LinkProblem.o: In der Funktion `main ': /home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefinierter Verweis auf `SomeClass :: close () ' ./src/LinkProblem.o: In der Funktion `SomeOtherClass ': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefinierter Verweis auf `SomeClass :: SomeClass () ' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefinierter Verweis auf "vtable for SomeOtherClass" /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefinierter Verweis auf `SomeClass :: ~ SomeClass () ' ./src/LinkProblem.o: In der Funktion `~ SomeOtherClass ': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefinierter Verweis auf "vtable for SomeOtherClass" /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefinierter Verweis auf `SomeClass :: ~ SomeClass () ' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefinierter Verweis auf `SomeClass :: ~ SomeClass () ' collect2: ld hat 1 Exit-Status zurückgegeben make: *** [LinkProblem] Fehler 1
c++
linker
g++
eclipse-cdt
Alex Black
quelle
quelle
Antworten:
Angenommen, diese Methoden befinden sich in einer der Bibliotheken, sieht es nach einem Bestellproblem aus.
Wenn Bibliotheken mit einer ausführbaren Datei verknüpft werden, erfolgen sie in der Reihenfolge, in der sie deklariert sind.
Außerdem verwendet der Linker nur die Methoden / Funktionen, die zum Auflösen der derzeit ausstehenden Abhängigkeiten erforderlich sind. Wenn eine nachfolgende Bibliothek dann Methoden / Funktionen verwendet, die ursprünglich von den Objekten nicht benötigt wurden, fehlen Abhängigkeiten.
Wie es funktioniert:
Beispiel:
Objekte erfordern:
Lib 1 bietet:
Lib 2 bietet
Wenn so verlinkt:
Dann kann der Linker die Lese- und Schreibsymbole nicht auflösen.
Aber wenn ich die Anwendung so verlinke:
Dann wird es richtig verlinken. As l2 löst die Abhängigkeiten BatchRead und BatchWrite auf, fügt aber auch zwei neue hinzu (Lesen und Schreiben). Wenn wir als nächstes mit l1 verknüpfen, werden alle vier Abhängigkeiten aufgelöst.
quelle
Dieser Linkerfehler bedeutet normalerweise (meiner Erfahrung nach), dass Sie eine virtuelle Funktion in einer untergeordneten Klasse mit einer Deklaration überschrieben haben, aber keine Definition für die Methode angegeben haben. Zum Beispiel:
class Base { virtual void f() = 0; } class Derived : public Base { void f(); }
Aber Sie haben die Definition von f nicht gegeben. Wenn Sie die Klasse verwenden, wird der Linkerfehler angezeigt. Ähnlich wie bei einem normalen Linkerfehler wusste der Compiler, wovon Sie sprachen, aber der Linker konnte die Definition nicht finden. Es ist nur eine sehr schwer zu verstehende Botschaft.
quelle
Qt C ++ zeigt diesen Fehler an, wenn Sie eine Klasse so ändern, dass sie jetzt von QObject erbt (dh damit sie jetzt Signale / Slots verwenden kann). Wenn Sie qmake -r ausführen, wird moc aufgerufen und dieses Problem behoben.
Wenn Sie über eine Versionskontrolle mit anderen zusammenarbeiten, möchten Sie einige Änderungen an Ihrer .pro-Datei vornehmen (dh eine leere Zeile hinzufügen / entfernen). Wenn alle anderen Ihre Änderungen erhalten und make ausführen, sieht make, dass sich die .pro-Datei geändert hat, und führt qmake automatisch aus. Dies erspart Ihren Teamkollegen, Ihre Frustration zu wiederholen.
quelle
Das Problem stellte sich für mich als ziemlich dunkel heraus. Meine Klasse sah so aus:
//----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() { } virtual int foo() { return 0; } }; //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" //----------------------------------------- //----------------------------------------- // main.h class derived : public base { public: virtual int foo() ; }; //----------------------------------------- //----------------------------------------- // main.cpp int main () { derived d; } //-----------------------------------------
Das Problem liegt im Linker. Meine Header-Datei befand sich irgendwo in einer Bibliothek, aber alle virtuellen Funktionen wurden in der Klassendeklaration als "inline" deklariert. Da (noch) kein Code für die virtuellen Funktionen vorhanden war, hat der Compiler oder Linker es versäumt, tatsächliche Funktionskörper einzurichten. Es konnte auch die vtable nicht erstellt werden.
In meinem Hauptcode, in dem ich von dieser Klasse abgeleitet habe, hat der Linker versucht, meine Klasse mit der Basisklasse und seiner vtable zu verbinden. Aber die vtable war verworfen worden.
Die Lösung bestand darin, mindestens einen der Körper der virtuellen Funktionen außerhalb der Klassendeklaration wie folgt zu deklarieren:
//----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() ; //-- No longer declared 'inline' virtual int foo() { return 0; } }; //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" base::~base() { } //-----------------------------------------
quelle
In Bezug auf Probleme mit Qt4 konnte ich die oben erwähnte Option qmake moc nicht verwenden. Aber das war sowieso nicht das Problem. Ich hatte den folgenden Code in der Klassendefinition:
class ScreenWidget : public QGLWidget { Q_OBJECT // must include this if you use Qt signals/slots ... };
Ich musste die Zeile "Q_OBJECT" entfernen, da keine Signale oder Slots definiert waren.
quelle
Ich hatte diese Fehlermeldung. Das Problem war, dass ich einen virtuellen Destruktor in der Header-Datei deklariert habe ,, aber der Körper der virtuellen Funktionen wurde tatsächlich nicht implementiert.
quelle
Dieser Fehler tritt auch auf, wenn wir einfach eine virtuelle Funktion ohne Definition in der Basisklasse deklarieren.
Zum Beispiel:
class Base { virtual void method1(); // throws undefined reference error. }
Ändern Sie die obige Deklaration in die unten stehende, es wird gut funktionieren.
class Base { virtual void method1() { } }
quelle
In meinem Fall trat das Problem auf, als ich vergaß, die = 0 für eine Funktion in meiner reinen virtuellen Klasse hinzuzufügen. Es wurde behoben, als = 0 hinzugefügt wurde. Das gleiche wie für Frank oben.
class ISettings { public: virtual ~ISettings() {}; virtual void OKFunction() =0; virtual void ProblemFunction(); // missing =0 }; class Settings : ISettings { virtual ~Settings() {}; void OKFunction(); void ProblemFunction(); }; void Settings::OKFunction() { //stuff } void Settings::ProblemFunction() { //stuff }
quelle
Ich bin jetzt auch über das Thema gestolpert. Die Anwendung definierte eine reine virtuelle Schnittstellenklasse und eine benutzerdefinierte Klasse, die über eine gemeinsam genutzte Bibliothek bereitgestellt wurde, sollte die Schnittstelle implementieren. Beim Verknüpfen der Anwendung beschwerte sich der Linker, dass die gemeinsam genutzte Bibliothek weder vtable und type_info für die Basisklasse bereitstellen würde, noch dass sie irgendwo anders gefunden werden könnten. Es stellte sich heraus, dass ich einfach vergessen habe, eine der Methoden der Schnittstelle rein virtuell zu machen (dh das "= 0" am Ende der Deklaration weggelassen. Sehr rudimentär, immer noch leicht zu übersehen und rätselhaft, wenn Sie die Linkerdiagnose nicht mit der verbinden können Ursache.
quelle
Ich hatte diese Fehlermeldung, als ich "Hallo Welt" wie Dinge mit Qt versuchte. Die Probleme wurden behoben, indem der qt moc (Meta Object Compiler) korrekt ausgeführt und + einschließlich dieser von moc generierten Dateien korrekt kompiliert wurde.
quelle
Wenn Sie eine Basisklasse mit einer reinen virtuellen Funktion haben, stellen Sie sicher, dass Ihr Basisklassenkonstruktor und -destruktor einen Body hat, andernfalls schlägt der Linker fehl.
quelle
Ich stelle dies für zukünftige Besucher:
Wenn beim Erstellen eines
Exception
Objekts der Fehler angezeigt wird, liegt die Ursache wahrscheinlich in der fehlenden Definition derwhat()
virtuellen Funktion.quelle