Vor ein paar Wochen bin ich beim programmieren auf ein Problem gestoßen, dessen Lösung mich viel Zeit gekostet hat und die ich nicht im Internet gefunden habe. Aus diesem Grund möchte ich einen kurzen Artikel dazu online bringen, damit andere Suchende mehr Glück als ich im Netz haben.
Die Ausgangssituation war folgende: Ich wollte ein Programm in C/C++ schreiben und musste dabei auf Bibliotheken zurück greifen, die zu einem Teil mit dem C-Compiler von gcc compiliert wurden und zum anderen Teil mit dem C++-Compiler von gcc. Da ich in meinem Programm Objekte von Klassen aus den „C++-Bibliotheken“ erstellen wollte, musste ich mein Programm folglich auch mit dem C++-Compiler von gcc erstellen. Darüber hinaus wollte ich aber auch Funktionen aus dem „C-Teil“ der Bibliotheken verwenden. Und genau da begann mein Problem.
Das Compilieren meines Programms stellte überhaupt kein Problem dar, zumindest so lange ich die Header-Dateien der verwendeten Bibliotheken angegeben habe (ist ja klar). Das anschließende Linken meines Programms mit den Bibliotheken ging jedoch sauber schief: An allen Stellen, an denen ich auf eine Funktion zugreifen wollte, die sich in einer mit dem C-Compiler von gcc compilierten Bibliothek befand, lieferte mir der Linker eine Fehlermeldung. Compilierte ich stattdessen mein Programm mit dem C-Compiler von gcc, konnte ich zwar auf die Funktionen der mit dem C-Compiler von gcc compilierten Bibliotheken zugreifen, musste aber im Gegenzug auf die mit dem C++-Compiler von gcc compilierten Bibliotheken verzichten und konnte natürlich auch keine C++-Features wie Objektorientierung verwenden. Anscheinend findet der C++-Linker von gcc keine Funktionen in mit dem C-Compiler compilierten Bibliotheken (unter Linux Shared Objects).
Die Lösung: Einfach dem C++-Compiler mitteilen, welche Bibliotheken früher mal C-Code waren und welche C++-Code. Dies macht man mittels dem Include der Headerdateien wie folgt: Header von mit dem C++-Compilier compilierten Bibliotheken bindet man einfach wie gewohnt mit #include "c++_bibliothek.hh" ein. Will man jedoch in seinem C++-Programm auf eine mit dem C-Compiler compilierte Bibliothek zugreifen, umrahmt man den Include der entsprechenden Headerdatei mit extern "C" {...}.
In einem Beispiel sieht das wie folgt aus:
// Compilereigene Bibliotheken.
#include <math.h>
#include <stdio.h>
// Mit dem C-Compiler compilierte Bibliotheken.
extern "C" {
#include "c_bibliothek.h"
}
// Mit dem C++-Compiler compilierte Bibliotheken.
#include "c++_bibliothek.hh"
Leider konnte ich die oben erwähnte Linker-Fehlermeldung nicht mehr reproduzieren da bei meiner aktuellen Softwareausstattung (Ubuntu 8.10, Eclipse 3.4 mit CDT 5.0.1, gcc 4.3) das oben erläuterte Problem gar nicht mehr auftritt und deshalb auch der hier vorgestellte Workaround nicht mehr notwendig war.
Schreibe einen Kommentar