STL in DLL? Ja oder Nein, was macht Sinn?!?!



  • Hallo,
    danke für den Link.
    Also wenn ich das richtig verstanden habe, dann gibt es entweder viel arbeit, oder ein "Warning disable".

    Gut: Ich hab Ergeiz und bin (fast) jung, ich nehm die Arbeit. Außerdem hab ich ja momentan "nur" eine Liste (wird sicherlich noch mehr, aber was soll's) und ich will ja auch was lernen! Es ist zwar nicht umbedingt nur der Weg das Ziel, aber ich würde mit gerne eine Karte erarbeiten.

    Also müsste ich das jetzt ungefähr folgt machen?

    #ifdef _WINDLL // Wenn DLL-Exportiert wird
    
    /*
    #define EXPORT_STL_LIST(declspec_, T_) \
    	S3D_DLL_PRE_TEMPLATE template class declspec_ std::allocator<T_ >; \
    	S3D_DLL_PRE_TEMPLATE template class declspec_ std::allocator<std::_List_nod<T_, std::allocator<T_ > >::_Node>; \
    	S3D_DLL_PRE_TEMPLATE template class declspec_ std::allocator<std::_List_nod<T_, std::allocator<T_ > >::_Node*>; \
    	S3D_DLL_PRE_TEMPLATE template class declspec_ std::list<T_ >; 
    */
    
    #include <list>
    class S3D_DLL_PRE TyS3dActionBaseListAllocator
    	: public std::allocator<S3dActionBase*> {};
    class S3D_DLL_PRE TyS3dActionBaseListAllocatorListNode
    	: public std::allocator<std::_List_nod<S3dActionBase* , TyS3dActionBaseListAllocator >::_Node> {};
    class S3D_DLL_PRE TyS3dActionBaseListAllocatorListNodeP
    	: public std::allocator<std::_List_nod<S3dActionBase* , TyS3dActionBaseListAllocator >::_Node*> {};
    class S3D_DLL_PRE TyS3dActionBaseList
    	: public std::list<S3dActionBase*, TyS3dActionBaseListAllocator> {};
    
    #else // _WINDLL
    
    #include <list>
    typedef std::list<S3dActionBase*> TyS3dActionBaseList;
    
    #endif // _WINDLL
    
    class MySammlung
    {
    protected:
      TyS3dActionBaseList MyList;
    
    public:
      void AddToListe(S3dActionBase* ToAdd); // MyList.push_back();
      bool RemoveFromListe(S3dActionBase* ToRemove); // if (find(ToRemove)) {remove());
    }
    

    Das ganze strahlt natürlich noch vor Fehlermeldungen und Zugriffrechtproblemen (protected), aber ich würde gerne kurz nachfragen, ob das der richtige Weg ist?

    Vielen Dank,
    Hoffnungvoll,
    Stefan



  • Die STL hat in einem dll Interface nix verloren, das gibt früher oder später nur Probleme...

    Du solltest dir auch bewusst sein dass das Exportieren von Klassen in dlls nur ein compilerspezifisches Komfortfeature ist und absolut nicht portabel. Die so erzeugten dlls kannst du nur mit MSVC verwenden und du bist auch dort auf load time dynamic linking beschränkt usw.



  • Und warum musst Du dazu STL Klassen exportieren?
    Benutze sie doch einfach. Was musst Du da exportieren?
    Was versprichst Du Dir davon?
    Wenn Du Code-Optimierung willst benutze "Whole Program Optimization" des Compilers/Linkers.

    Achte darauf dass die Libs, DLLs und EXEs garantiert mit dem selben Compiler und SP erzeugt wurden.
    - und -
    Das geht nur, wenn auch die DLL Version der CRT verwendet wird. Deine Header sollten diese Nutzung unbedingt aprüfen und einen #error auswerfen wenn diese Settingsnicht gegeben sind.

    Du bekommst immer dann Probleme mit diesen Klassen wenn statische Member verwendet werden.



  • dot schrieb:

    Die STL hat in einem dll Interface nix verloren, das gibt früher oder später nur Probleme...

    Du solltest dir auch bewusst sein dass das Exportieren von Klassen in dlls nur ein compilerspezifisches Komfortfeature ist und absolut nicht portabel. Die so erzeugten dlls kannst du nur mit MSVC verwenden und du bist auch dort auf load time dynamic linking beschränkt usw.

    OK, wenn das so ist, akzeptier ich das dann. Aber nach wie vor hab ich dann ein Problem:

    class DLL_EXPORT MyClass
    {
    protected:
      std::list<ClassB*> MyListe;
    public:
      void AddToList(ClassB* ToAdd);
    };
    

    Wie löse ich das nun?
    Irgendwie fehlt mir jetzt die "Best Practise" zu dem Thema. Auch der Link von Nexus sagt mir "nur" was ich tun kann, aber gibt jetzt nicht aufschluss auf die Praxis. Es ist doch so, dass 80% der Programmierungen drehen sich um irdenwelche Daten und Verwaltung von Listen. Genau deswegen gibt es die STL ja. Wenn ich die in DLLs nicht verwenden darf/soll, was tu ich dann?

    Sorry, aber ich bekomme gerade keinen klaren Gedanken wie man das nun "richtig" löst.

    1.) Ich soll STL nicht exportieren, weil das zu Problemen mit verschiedenen Comps führen kann (oder gar "nur" mit MSVC klappt?)
    2.) Ich soll die Warning nicht deaktivieren, weil (Zitat aus anderem Thread) "Eine Warnung ja immer einen Grund hat".
    3.) Ich soll die STL nicht in Klassen erben, und mit exportieren, weil das Overhead gibt und nicht kompatibel ist.

    Also was man ich dann?

    Im Endeffekt möchte ich ja die STL-Klassen gar nicht exportieren, sondern nur anwenden. Ich will die nicht mal public machen, sondern "nur" intern in meinen Klassen verwenden und nur über eigenen Klassenfunktionen verarbeiten (also füllen, sotieren, etc).

    Jetzt bitte ich um Hilfe, nach der Frage des Lebens, dem Sinn und überhaupt nach allem....nö...stopp, das war irgend ein anderes Buch mit "Anhaltern" und "Galaxis"..

    Nochmal:
    Ich bitte um Hilfe der "Best Practis". Wie löst man das am sinnvollsten. Ich werde sicherlich keine DLL mit einem Compiler schreiben und diese mit einem anderen Compiler verwenden. Aber was gut wäre ist, wenn ich zur neuen DLL nicht umbedingt eine neue Exe schreiben müsste (also vorrausgesetzt der Header ist identisch).

    Geht das überhaupt sinnvoll, oder gibt es da für jedes Projekt Fallentscheidungen.

    Vielen Dank,
    und sorry dass ich jetzt einfach mal so "grundsätzlich" fragen muss.
    Stefan



  • Martin Richter schrieb:

    Und warum musst Du dazu STL Klassen exportieren?
    Benutze sie doch einfach. Was musst Du da exportieren?
    Was versprichst Du Dir davon?
    Wenn Du Code-Optimierung willst benutze "Whole Program Optimization" des Compilers/Linkers.

    Achte darauf dass die Libs, DLLs und EXEs garantiert mit dem selben Compiler und SP erzeugt wurden.
    - und -
    Das geht nur, wenn auch die DLL Version der CRT verwendet wird. Deine Header sollten diese Nutzung unbedingt aprüfen und einen #error auswerfen wenn diese Settingsnicht gegeben sind.

    Du bekommst immer dann Probleme mit diesen Klassen wenn statische Member verwendet werden.

    Hallo,
    habe deinen Beitrag jetzt eben erst gesehen.
    Was ich mir davon verspreche? Nun eigentlich habe ich in den Tutprials es damals so verstanden dass ich das muss. Wollen tu ich das nicht. Nur wenn es nötig ist.
    Mir ist es das liebste, ich habe "nur" die Endklassen im Export.

    Also verstehe ich dich richtig? Wenn ich die Klassen "nur anwende" dann einfach Warning aus und es ist gut?

    Danke,
    Stefan



  • Wenn Du diese Klasse exportierst müsstest Du kein Problem bekommen.

    class DLL_EXPORT MyClass 
    { 
    protected: 
      std::list<ClassB*> MyListe; 
    public: 
      void AddToList(ClassB* ToAdd); 
    };
    

    Damit musst Du die STL doch nicht exportieren. Hier feheln in jedem Fall die Konsruktoren, damit auch Deine Implementierung verwendet wird!
    Letzten Endes liegt die Implementierung ja in AddToList und niemand sonst muss sehen wie die interne Klasse aussieht.

    Je nach Design der Lib/DLL musst Du unterscheiden. Wenn DLLs und EXEs immer als paar ausgeliefert werden kann man auch solche Klassen exportieren. SOll die DLL unabhängig laufen dann kann man von solchen Konzepten und Klassen nur abraten. Dann solltest Du auf ein pures Interface System umschwenken.
    Bleibt also die Frage, warum Deine Klasse überhaupt Daten-Member hat und nicht pure Interfaces verwendet.

    Warnungen ausschalten solltest Du in keinem Fall.

    BTW: Pimpl gibt es auch ncoh.



  • Absolute Best Practise wäre es in einem dll Interface nur einfache Funktionen und primitive Datentypen (PODs) zu haben. Das Nächstbeste was du tun kannst wäre es dann wohl wie schon angesprochen nur Interfaces zu verwenden. Das funktioniert mit gewissen Einschränkungen noch ganz gut.



  • Danke schon mal,

    also wenn ich das richtig verstanden habe liegt mein Problem eher am:
    - Wie schreibe ich ein gutes Interface

    Denn dann spar ich mir ja viel export und import-Arbeit.

    Das wird happig bei meinen Strukturen.
    Derzeit ist es so, dass die DLL immer mit der Exe ausgeliefert wird, es soll aber auch DLLs geben die separat laufen. Also fehlt mir einfach noch der "richtige Dreh" für ein Interface.

    Also gut, dann werd ich mir mal ein Buch suchen, wo ich mal etas mehr über Interface und DLL lernen kann.
    Jemand eine Buchempfehlung?

    Viele Grüße,
    Stefan



  • Wenn eine DLL separat ausgeliefert werden soll, dann dürfen in keinem Fall im Header Objekte sein deren Layout sich je Compiler Version ändert...

    Ein gutes DLL Interfcae verwendet z.B. auch nur PODs.
    Klassen exportieren würde ich niermals, wenn es um losgelöste DLLs geht. Das kann immer nur mit einer Compilerversion funktionieren.



  • Hallo,
    dazu noch eine Frage (so rein um es zu verstehen).

    Ich nutze derzeit oftmals wxWidgets. Und meist auch ImageMagick.
    Beides gibt es ja für C++.
    Wenn ich beides als LIB in mein Projekt hole, bekomme ich vom Linker viele viele Fehler über doppelten Code.

    Beide sagen, ich solle als DLL einbinden. Also schnell beides als DLL durch den Compiler durchgelassen und eingebunden: geht! Kein doppelter Code.

    Die nutzen aber jetzt kein Interface. Ich habe Header-Dateien zu DLL und kann somit direkt linken. Ich vermute jetzt, dass liegt daran, weil ich die DLL und Exe in einem Zug mit dem gleichen Compiler gebaut habe. Ich muss allerdings jetzt auch die DLL-Dateien mit ausliefern. Und wenn sich an der DLL was ändert (z.B. neue Version oder Updates) muss ich die Exe auch neu schreiben.

    Wenn ich euch richtig verstanden habe, ist das jetzt aber nicht gerade eine gute Lösung. Bzw nur so lange eine akzeptable Lösung, solang wxWidgets nicht mit ImageMagick versucht zu komunizieren. (Was sicherlich nicht passiert, weil die zwei ja so nix miteinander zu tun haben).

    Sinnvoller wäre es, beide als Lib einzubinden und nur den gemeinsamen Code in eine DLL zu exportieren, welches über ein Interface angesprochen wird.
    (Was sich sicherlich nicht machen lässt ohne wxWidgets und ImageMagick selbst in die Hand zu nehmen und darin rumzubasteln.)

    Wenn ich das jetzt richtig verstanden habe, dann bin ich auch schon friedlich, schließe den Post als "gelöst" und werde meine Programmierer-Struktur-DLL-Lib-Interface-Gedanken für meine eigenen SDKs neu überdenken.

    Vielen Dank,
    Stefan


Anmelden zum Antworten