2016-04-27 8 views
1

Ich bin nicht ganz sicher, wo mein Problem ist.QT Creator Linker Fehler: Link2019 Datei nicht gefunden

Ich verwende Qt Creator für ein OpenGL-Projekt, und zum ersten Mal habe ich versucht, meinem Projekt noch ein paar Klassen hinzuzufügen. Ich habe Header- und Implementierungsdateien hinzugefügt: terrain.h, terrain.cpp, imageloader.h und imageloader.cpp.

Ich glaube, mein Problem in meinem .proDatei liegt:

HEADERS += glwidget.h \ 
imageloader.h \ 
terrain.h 
SOURCES += glwidget.cpp main.cpp \ 
imageloader.cpp \ 
terrain.cpp 

QT += opengl 
CONFIG -= app_bundle 
CONFIG += console c++11 
INCLUDEPATH += "../include" 
INCLUDEPATH += $$PWD 

RESOURCES += shaders.qrc 

Als ich qmake laufen, keine Fehler vorhanden sind.

Dann, als ich bauen das Projekt (nach der Reinigung, Laufen Qmake), habe ich die folgende Fehlermeldung erhalten:

glwidget.obj:-1: error: LNK2019: unresolved external symbol "private: static class Terrain * __cdecl GLWidget::loadTerrain(char const *,float)" ([email protected]@@[email protected]@[email protected]) referenced in function "protected: virtual void __cdecl GLWidget::initializeGL(void)" ([email protected]@@MEAAXXZ) 

Qt Creator sagt auch: Datei nicht gefunden glwidget.obj

jedoch die Problem scheint wirklich mit der Geländeklasse zu sein, oder wie es mit glwidget interagiert.

Wenn ich alle Verweise auf Terrain entferne, funktioniert der Build einwandfrei.

jedoch, wenn ich die folgende Zeile in der initializeGL() Methode glwidget.cpp die LINK2019 Fehler angezeigt:

terrain = loadTerrain("test.bmp", 20); 

Gelände in glwidget.h als eine Instanz der Klasse von Terrain Gelände definiert sind CPP:

Terrain* terrain; 

Und loadTerrain ist in glwidget.h wie folgt definiert:

static Terrain* loadTerrain(const char* filename, float height); 

Interessanterweise tritt dieser Fehler auf, selbst wenn die Implementierung von loadTearain auskommentiert ist.

Hier sind ein paar Dinge, die ich versucht habe:

Als ich vor oder nach Qmake sauber laufen, oder den OBJ-Dateien in dem Build-Ordner löschen, gibt es keine Änderung. Ich habe festgestellt, dass glwidget.obj sowie terrain.obj erscheinen, wenn das Projekt neu erstellt wird.

Jede Hilfe wird geschätzt. Lassen Sie mich wissen, wenn Sie irgendwelche meiner Akten sehen möchten.

BEARBEITEN Sie: Das Problem bleibt bestehen, auch nachdem die Methode loadTerrain() nicht statisch gemacht wurde.

EDIT 2 ich auch den zweiten Fehler zu haben schien vergessen, dass es wirft, obwohl ich nicht sicher bin, dass dies nicht mehr helfen:

debug\program2.exe:-1: error: LNK1120: 1 unresolved externals 

debug ist der Ordner, in dem die. obj erscheint und program2 ist der Name des Projekts.


BEHOBEN! Es stellt sich heraus, dass die Methode statisch war das Problem. Sie können keine statische Methode in Headerdateien deklarieren, die von mehreren Quellen in der Art und Weise verwendet werden, wie ich es getan habe.I ersetzt:

static Terrain* loadTerrain(const char* filename, float height); 

mit

Terrain* GLWidget::loadTerrain(const char* filename, float height); 

Neben den nachfolgenden Aufrufen der Methode zu ändern.

Danke für Ihre Hilfe!

+0

Es scheint, Sie verpassen die Implementierung von LoadTerrain in cpp-Datei? – demonplus

+0

Ich habe eine Implementierung auskommentiert, aber die Auskommentierung scheint nicht zu helfen. –

+0

Wenn die Implementierung auskommentiert ist, bedeutet dies, dass Sie keine Implementierung haben. Könnten Sie bitte verwandte Teile Ihrer Kopf- und Quelldateien posten? – demonplus

Antwort

1

Durch die Funktion static gab es interne Verknüpfung. Dies bedeutet, dass die Definition Ihrer Funktion nur in der Übersetzungseinheit gefunden wird, in der sie definiert ist (d. H.) und nicht main.cpp. Entfernen Sie das statische Schlüsselwort.

Dies ist sehr einfach mit objdump zu bestätigen. Sagen Sie bitte test.h haben:

#ifndef _TEST_H 
#define _TEST_H 

static void a_func(); 

#endif 

test.cpp:

#include "test.h" 

void a_func() 
{ 
} 

main.cpp:

#include "test.h" 

void a_func() 
{ 
} 

int main() 
{ 
} 

Sie werden feststellen, dass Sie keine Funktion Neudefinition Fehler bekommen. Wir können jede Datei kompilieren getrennt, die Objekte zu inspizieren:

Disassembly of section .text: 

0000000000000000 <_ZL6a_funcv>: 
    0: 55      push %rbp 
    1: 48 89 e5    mov %rsp,%rbp 
    4: 90      nop 
    5: 5d      pop %rbp 
    6: c3      retq 

Was ist nun die letzte binary:

g++ -c test.cpp -o test.o 
g++ -c main.cpp -o main.o 

Beide a_func zeigen?

g++ main.o test.o

objdump -d ./a.out

00000000004005b6 <_ZL6a_funcv>: 
    4005b6: 55      push %rbp 
    4005b7: 48 89 e5    mov %rsp,%rbp 
    4005ba: 90      nop 
    4005bb: 5d      pop %rbp 
    4005bc: c3      retq 

00000000004005bd <main>: 
    4005bd: 55      push %rbp 
    4005be: 48 89 e5    mov %rsp,%rbp 
    4005c1: b8 00 00 00 00   mov $0x0,%eax 
    4005c6: 5d      pop %rbp 
    4005c7: c3      retq 

00000000004005c8 <_ZL6a_funcv>: 
    4005c8: 55      push %rbp 
    4005c9: 48 89 e5    mov %rsp,%rbp 
    4005cc: 90      nop 
    4005cd: 5d      pop %rbp 
    4005ce: c3      retq 
    4005cf: 90      nop 

Es erscheint zweimal! Aus diesem Grund machen Sie in einer Header-Datei, die für mehrere Übersetzungseinheiten freigegeben werden soll, keine statischen Funktionen.

+0

Das macht Sinn, wenn man die Methode statisch macht, würde ein Problem verursachen. Allerdings habe ich es nicht statisch gemacht, das Projekt geputzt, qmake ausgeführt und neu aufgebaut, und das Problem bleibt bestehen ... –

+0

Ich ignoriere meinen letzten Kommentar. Nachdem ich es nicht-statisch gemacht hatte, musste ich daran denken, das GLWidget :: -Präfix dem Methodenaufruf, der Deklaration und der Implementierung hinzuzufügen. Sobald ich das getan habe und reraran qmake, hat es funktioniert! Ich verbringe viel Zeit mit dem Problem. Danke für Ihre Hilfe. –

+0

Ich würde Ihre Antwort auffrischen, aber mir fehlt der erforderliche Ruf! –

0

Es scheint, Sie Umsetzung der Funktion loadTerrain() in glwidget.cpp fehlt:

Terrain* loadTerrain(const char* fileName, float height) 
{ 
    // your implementation here 
} 

Sie here für eine Probe aussehen.

+0

Ich hatte eine Implementierung, aber es wurde auskommentiert. Ich habe es (und machte es nicht statisch, um dem oben gegebenen Ratschlag zu folgen) zu keinem Glück befragt. –