ZFX
ZFX Neu
Home
Community
Neueste Posts
Chat
FAQ
IOTW
Tutorials
Bücher
zfxCON
ZFXCE
Mathlib
ASSIMP
NES
Wir über uns
Impressum
Regeln
Suchen
Mitgliederliste
Membername:
Passwort:
Besucher:
4370321
Jetzt (Chat):
24 (0)
Mitglieder:
5239
Themen:
24223
Nachrichten:
234554
Neuestes Mitglied:
-insane-

FAQ - Frequently Asked Questions - Allgemeine Programmierung


Compiler-Firewalls, Minimieren der Übersetzungsabhängigkeiten & C4251 bei dll Verwendung.

Allgemeine Erklärungen

Willkommen auf der dunklen Seite von C++. Der Export von Templates in DLLs ist eines der grössten Probleme aktueller Compiler und wurde auch im Standard nicht klar umrissen. Beim instantiieren einer Klasse, die in einer DLL liegt muss nämlich das Programm auf der Client-Seite auch die Basisklassen und statischen members instantiieren, die müssen also alle exportiert sein - was nun bei Templates problematisch ist.
Es gibt nämlich noch ein weiteres Problem: Wenn beim Nutzer der DLL eine andere Implementation der STL installiert ist (z.B. STLport + Mitgelieferte MS-STL) wird der Client andere Datenstrukturen anlegen, als der in der DLL enthaltene Code erwartet.

von Cygon

Die Lösungen:

- Instantiiere deine templates nur innerhalb der DLL. Dazu musst du sämtliche template-Variablen als Pointer deklarieren und den explizit im Konstructor mit 'new' erstellen (z.B. std::list *m_pChildlist).

- Exportiere deine Klassen nicht. Der Export ist nur nötig, um Clients deiner DLL zu ermöglichen, eine Klasse direkt mit 'new' anzulegen. Als Ersatz musst du dann in der DLL eine Funktion wie z.B. CResourceTree *newResTree(); zur Verfügung stellen. Und natürlich void deleteResTree(CResourceTree *);...

- Ignoriere die Warnungen. Dann musst du nur für die Nutzer deiner DLL genau kenntlich machen, mit welchen Compiler und STL-Versionen diese kompiliert wurden - sonst kommt es zu den ulkigsten Fehlern.

von Cygon

Alternativen

Das Problem kann auch dadurch gelöst werden, dass man die Elemente der Klasse einzeln exportiert.

Die eleganteste Lösung ist wohl eine reine Interface Klasse, welche die Kritischen Teile vor dem Anwender "versteckt". [vgl. Compiler-Firewalls und das Pimpl-Idiom in Herb Sutter, Exceptional C++]
Die privaten Elemente der Klasse wandern vollständig in eine Struktur, die in der cpp definiert und deklariert ist. Das Interface (und damit die Header) enthalten nur einen undurchsichtigen private Zeiger auf diese forward definierte Struktur.
Diese Variante minimiert die Übersetzungsabhängigkeiten, es muss nicht daller abhängige Code neu compiliert werden, wenn die private Schnittstelle der Klasse sich ändert.

von Mastermind