3 Beispiel einer dynamisch ladbaren Bibliothek

Für die folgenden Beispiele wird eine kleine Bibliothek verwendet, die zwei Funktionen enthält:

  1. Die Funktion int summe( int a, int b ) bekommt zwei Argumente, und liefert die Summe der beiden.
  2. Dagegen bekommt int immereinsmehr( void ) nichts übergeben; beim ersten Aufruf liefert die Funktion den Wert 0, und bei den folgenden Aufruf jeweils einen um 1 höheren Wert.

Tip C++: Ein C++-Compiler erzeugt aus den Funktionsnamen, die der Programmierer vorsieht, und einer Kodierung der Parameterliste ziemlich kryptische tatsächliche Funktionsnamen (name mangling), um ein Überladen von Funktionen mit verschiedenen Parameterlisten (Signaturen) zu ermöglichen. Dies ist nett gemeint, aber sehr ärgerlich wenn man die Bibliothek zur Laufzeit dynamisch nachladen möchte. Denn um die Zeiger auf die Funktionen zu bekommen, muß man ihre vollen Namen wissen.

Die Funktion int summe( int a, int b ) (ohne extern "C") wird vom g++ unter Linux beispielsweise mit dem Namen summe__Fii behandelt; der Visual C++ unter Windows macht daraus ein leicht zu merkendes ?summe@@YAHHH@Z.

Deshalb ist es oft handlicher, die Schnittstelle zwischen Aufrufer und der Bibliothek als extern "C" zu deklarieren. Dann verwenden Compiler und Linker die unter C übliche Namensgebung; die vom Programmierer vergebenen Namen werden also beibehalten.

So wird auch in diesen Beispielen verfahren.

Trotz des Umsetzens des Aufrufs auf C-Konventionen ist es aber nach wie vor möglich, ober- und unterhalb der Schnittstelle C++ zu verwenden. Insbesondere können in einer Bibliothek Ausnahmen geworfen werden, die im aufrufenden Programm gefangen werden. (Das funktioniert sogar unter Windows.)

Falls man die Funktionen nutzen will, die als Einsprungpunkte dienen (_init() und _fini() unter Linux, oder DllMain() unter Windows) dann müssen diese nach C-Konvention benannt sein; wenn man seine Bibliothek in C++ schreibt, muß man also diese Funktionen als extern "C" deklarieren.



Unterabschnitte
www.wachtler.de