2010-08-24 10 views
6

Ich arbeite an einem Projekt, das mehrere ähnliche Codepfade hat, die ich vom Hauptprojekt in Plugins trennen möchte. Das Projekt muss plattformübergreifend kompatibel bleiben, und alle APIs zum Laden dynamischer Bibliotheken, die ich untersucht habe, sind plattformspezifisch.Was ist der einfachste Weg, um portable, dynamisch ladbare Bibliotheken in C++ zu schreiben?

Was ist die einfachste Möglichkeit, ein dynamisches System zum Laden von Bibliotheken zu erstellen, das kompiliert und auf mehreren Betriebssystemen ausgeführt werden kann, ohne dass der Code geändert werden muss? Idealerweise würde ich gerne ein Plugin schreiben und es auf allen Betriebssystemen laufen lassen, die das Projekt unterstützt.

Danke.

Antwort

7

Sie müssen plattformabhängigen Code für das Ladesystem verwenden. Es ist anders, eine DLL unter Windows zu laden, als ein gemeinsames Objekt in Unix zu laden. Aber mit ein paar #ifdef können Sie im Loader die gleiche Code-Basis haben.

Having said that, ich denke, Sie können Ihre Plugins plattformunabhängig machen. Natürlich müssen Sie es für jede Plattform kompilieren, aber der Code wird zu 99% gleich sein.

5

Dynamische Bibliothek lädt ein Windows und Unix/Linux arbeitet mit 3 Funktionen. Ein Paar Funktionen zum Laden/Entladen der Bibliotheken und eine weitere Funktion zum Abrufen der Adresse einer Funktion in der Bibliothek. Sie können leicht einen Wrapper um diese drei Funktionen schreiben, um Unterstützung für verschiedene Betriebssysteme zu bieten.

2

Werfen Sie einen Blick auf die boost.extension-Bibliothek, es ist nicht wirklich Teil von Boost, aber Sie können es in der Sandbox finden. Es ist auch irgendwie eingefroren, aber insgesamt ist die Bibliothek stabil und einfach zu bedienen.

4

Idealerweise würde ich gerne ein Plugin schreiben und es auf allen Betriebssystemen laufen lassen, die das Projekt unterstützt.

Nur wenige Dinge von oben auf den Kopf:

  • Vermeiden Sie statische Objekte in den dynamischen Bibliotheken. Stellen Sie geeignete Initialisierungsmethoden/Funktionen zur Verfügung, um die Objekte zuzuordnen. Die Probleme, die während des Ladens der Bibliothek durch das Betriebssystem auftreten (dies ist der Fall, wenn die c'tors für statische Objekte aufgerufen werden), sind sehr schwer zu debuggen - nur zu den Multi-Threading-Problemen.

  • Schnittstellenheader dürfen keinen Code enthalten. Keine Inline-Methoden, kein Präprozessor definiert. Dies soll verhindern, dass die Anwendung mit dem Code aus einer bestimmten Version der Bibliothek verschmutzt wird, was es unmöglich macht, die Bibliothek zu einem späteren Zeitpunkt zu ersetzen.

  • Interface-Header dürfen selbst keine Implementierungsklassen enthalten - nur abstrakte Klassen und factory functions. Ähnlich wie beim vorherigen Punkt hängt die Vermeidung der Anwendung von der jeweiligen Version der Klassen ab. Fabriken werden benötigt, damit Benutzeranwendungen die konkreten Implementierungsklassen instanziieren können.

  • Wenn Sie eine neue Version einer Schnittstelle einführen, um die Dinge irgendwie abwärtskompatibel zu halten, modifizieren Sie die vorhandene abstrakte Klasse nicht - erstellen Sie eine neue abstrakte Klasse und fügen Sie neue Methoden hinzu. Ändern Sie die Fabrik, um die neue Version zurückzugeben. (Rufen Sie MS 'IInterface, IInterface2, IInterface3 usw. auf.) Verwenden Sie in der Implementierung eine neuere Version der abstrakten Klasse. Das würde durch Polymorphie die Implementierung rückwärtskompatibel mit den älteren Schnittstellenversionen machen.(Das erfordert offensichtlich periodische Schnittstellenwartung und -bereinigungen - um die alte Gruft zu entfernen.)