2016-10-09 5 views
0

Ich schreibe eine Anwendung in D, die mit OpenGL und einigen anderen nativen Bibliotheken (mit den Derelict-Bibliotheken) Schnittstellen. Dieser Fehler scheint jedoch nichts damit zu tun zu haben.Linker Fehler: undefinierter Verweis auf `interne '

Immer, wenn ich „dub build“ tun gelingt die Zusammenstellung, aber ld nicht mit dieser Nachricht:

Linking... 
../git/mango-engine/bin/libmango-engine.a(gl_model_503_284.o):(.data._D12mango_engine8graphics6opengl8gl_model7GLModel6__initZ+0x10):  undefined reference to `internal' 
../git/mango-engine/bin/libmango-engine.a(shader_51b_52f.o): (.data._D12mango_engine8graphics6shader13ShaderProgram6__initZ+0x18):  undefined reference to `internal' 
collect2: error: ld returned 1 exit status 

Ich habe keine Ahnung, was das bedeutet, und haben sie noch nie gesehen. Seltsamerweise tritt dieser Fehler auch nur auf, wenn ich die spezifischen Dateien gl_model.d und shader.d aus einem anderen DUB-Projekt importiere. Wenn sie nicht importiert werden, ist der Linker erfolgreich.

Ich bin nicht sicher, welche Informationen zur Verfügung zu stellen, so dass ich verbinden die gesamte Quellcode here.

EDIT: Dieser Fehler tritt nur dann, wenn für x86_64 kompilieren. x86 funktioniert gut.

+0

Es gibt eine Funktion oder eine Variable wahrscheinlich markiert 'extern (C) void internal()' oder etwas, das erklärt, aber nicht definiert .. das 'Mango_engine.graphics' Modul, ist es Ihr Code oder aus einer Bibliothek? –

+0

@ AdamD.Ruppe Ich habe nur eine externe Anweisung im gesamten Projekt, und es hat eine Implementierung. Es wird auch nicht irgendwo in der Nähe von "internal" – jython234

Antwort

0

Ich habe es in den beiden Dateien auf zwei Zeilen aufgespürt (beide sind gleich):

private SyncLock lock = new SyncLock(); 

Wo SyncLock eine leere Klasse ist, die ich für „synchronisiert“ Blöcke verwenden (nicht sicher, ob das ist der richtige Weg, dies zu tun). Wenn ich die Initialisierung in den Konstruktor verschiebe, funktioniert es aus gutem Grund (keine Fehler).

+2

Initialisierung eines Klassenmembers ist völlig anders als ein Konstruktor ... ein Klassenmember ist * statisch * initialisiert, was bedeutet, dass die 'neue SyncLoc()' zur Kompilierzeit ausgeführt wird, und a Zeiger auf ein einzelnes Objekt in Daten wird Teil des Klasseninitialisierers ... bedeutet, dass ALLE Instanzen der Klasse die einzelne, statische Instanz von SyncLock teilen. Ein Konstruktor ist der Weg, es zu tun, wenn jede Instanz getrennt sein sollte (fast immer, was Sie wollen). Ich verstehe immer noch nicht, warum da ein "internes" Symbol drin ist, aber 'privates Objekt x = neues Objekt();' ist fast immer ein Anfängerfehler. –

+0

Und im Allgemeinen können Sie tun, was Sie wollen, ohne Sperre zu verwenden, wenn Sie Ihr Programm in einer gleichzeitigen Art und Weise schreiben. Lock-free-Programmierung ist der Weg zu gehen, denn Sperren sind eine teure Umgehung, für etwas, das Sie wahrscheinlich umgehen könnten. – Bauss

Verwandte Themen