Angenommen, ich habe zwei Projekte. Eine ist eine Anwendung und die andere ist eine gemeinsam genutzte Bibliothek, die allgemeinen, wiederverwendbaren Code enthält, der von mehr als nur dieser Anwendung verwendet werden kann.
Meine Anwendung verwendet STL und meine gemeinsam genutzte Bibliothek verwendet auch STL. Das erste Problem hier ist, dass meine gemeinsame Bibliothek STL verwendet. Wenn ich jemals eine neuere Version von STL in meine Anwendung einbaute, aber meine Shared Library nicht neu aufbaut, weil das nicht notwendig ist, haben wir sofort Kompatibilitätsprobleme.
Mein erster Gedanke, um dieses Problem zu lösen, ist, STL überhaupt nicht in der Schnittstelle zu den Shared-Library-Klassen zu verwenden. Nehmen wir an, wir haben eine Funktion in meiner Bibliothek, die eine Zeichenkette nimmt und etwas damit macht. Ich würde den Funktionsprototyp wie folgt aussehen lassen:
%Vor%anstelle von:
%Vor% Bei Strings wird das wahrscheinlich zwischen den verschiedenen Versionen von STL OK sein, aber der Nachteil ist, dass wir von std::string
zu char*
und zurück zu std::string
gehen, was Performance-Probleme verursacht / p>
Wird das Boxen / Unboxing von Rohtypen zu ihren STL-Gegenstücken empfohlen? Dies wird sogar noch schlimmer, wenn wir versuchen, dies zu einem std::list
zu tun, da es wirklich keinen "rohen Typ" gibt, von dem ich weiß, dass wir ihn problemlos weitergeben könnten, ohne eine Art O (n) oder ähnliche Operation auszuführen / p>
Welche Designs funktionieren in diesem Szenario am besten? Was sind die Vor- / Nachteile von jedem?
Einer der Vorteile des Ansatzes const char*
ist, dass Ihre Bibliothek auch von C aus aufgerufen werden kann, und somit auch von vielen anderen Sprachen, die an C angeschlossen sind (so ziemlich alles da draußen). Dies allein ist ein sehr interessantes Verkaufsargument.
Wenn Sie jedoch beide Bibliotheken schreiben und pflegen, und sie nur in C ++ verwendet werden (sagen wir für die nächsten 5 Jahre), würde ich nicht die Mühe machen, alles zu konvertieren. std::string
ist eine Sache, std::vector
oder std::map
wird nicht so gut konvertieren. Abgesehen davon, wie oft wechseln Sie zu einer anderen STL-Implementierung? Und wirst du in diesen Fällen wirklich "vergessen", deine Shared Library neu zu erstellen? Außerdem können Sie nach Bedarf C-Style-Wrapper schreiben / generieren.
Fazit (voreingenommen auf meine Erfahrungen mit dieser Angelegenheit): Wenn du kein C brauchst, gehe mit stl.
Sicher sollte die C ++ - Standardbibliothek genauso wie das virtuelle Tabellenlayout oder das Namensmangelschema als Teil von C ++ ABI betrachtet werden. Außerdem wirken sich inkompatible Änderungen im ABI eher auf obskure Eckfälle aus als auf das Layout von std :: vector. Mit anderen Worten: Wenn Sie eine C ++ - Bibliothek erstellen möchten, können Sie C ++ - Standardklassen verwenden.
Ein anderes Problem kann auftreten, wenn die Bibliothek einen anderen Heap verwendet als die Anwendung. Wenn dies der Fall ist oder dies der Fall sein kann, stellen Sie sicher, dass die Bibliothek ihren eigenen Speicher besitzt / verwaltet. Mehrere Heaps können ein Problem sein, wenn die Bibliothek eine andere C-Bibliothek verwendet und daher ein anderes malloc / free und daher ein anderer Heap. Ссылка
Viele A.P.I. und Shared Libraries verwenden "opaque" oder generische Zeiger als Argumente in Funktionen, um Unterschiede zwischen den Versionen zu vermeiden.
%Vor%Und manchmal, wenn eine Shared Library Funktion mehrere Argumente hat, werden sie durch einen Zeiger ersetzt, der ein Zeiger auf ein Array oder eine Struktur oder sogar eine Klasse sein soll.
Es hängt davon ab, wie Sie mit Ihrer Bibliothek arbeiten werden, da viele Bibliotheken wie normale C verwendet werden, auch wenn Sie C ++ verwenden.
Tags und Links c++ design-patterns stl design shared-libraries