Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

1

21.02.2007, 17:21

DLLs, STL und das Visual Studio

Ich dreh bald durch Oo Langsam aber sicher verstehe ich warum so ziemlich jede große Library einen Bogen um die STL macht und ihre eigenen Versionen von wichtigen Teilen derselben implementiert.

Die Situation:
Ich bin nach langem hin und her endlich dazu gekommen oft genutzte Codefragmente in eine eigene Library (-> DLL) zu packen. Also endlich kein nerviges herumkopieren von Quellcodedateien mehr (dachte ich ...). Einfach gegen die *.libs linken, den Header im VS bekannt machen und eben ab jetzt immer die DLL mitliefern.

Pustekuchen ... Ich mache viel und gern gebrauch von der STL, aber sobald man eine Klasse die diese benutzt per __declspec( dllexport ) in die DLL packen möchte ist total tote hose. Der Compiler schmeisst freundlicherweise noch eine Warnung und sobald ich an eine Stelle in der DLL komme, wo ich eine der STL Klassen benutzte gibts nen crash *juhu*

Als alternative hatte ich mir nun fast überlegt STLport zu verwenden, aber so richtig "Lust" habe ich darauf auch nicht ...

Kann mir jemand erklären wie ich das vllt noch anders umgehen kann? Ich hab mich bisher nicht über die Maßen mit DLLs beschäftigt und kann mir nicht vorstellen das ich nun auf die "mitgelieferte" STL wirklich verzichten muss. Es geht mir dabei nichtmal um totale Plattformunabhängigkeit.

Ausserdem dachte ich, das diese Probleme vonwegen DLL und STL nur dann auftuachen würden, wenn man das Programm mit einem anderen Compiler als die DLL kompiliert (da ja evtl verschiedene STL Versionen). Ich kompiliere aber naheliegenderweise beides mit demselben compiler ....

2

21.02.2007, 17:27

STLs(Standard Template Librarys) benutzen Templates, die werden aber vor der Laufzeit kompiliert. Du kannst es so umgehen, die Teile, wo du die STL Bestandteile benutzt, musst du inline in der Header deklarieren, so zB:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <map>
#include <string>
.
.
.

class __declspec(dllexport) Test
{
private:
   std::map<std::wstring ID, void* Reserved>
public:
    .
    .
    .
    inline void Testfunktion(void)
    {
        // Dein Code, der STL beeinhaltet

    }
};


Mitunter kann die Header dann richtig groß werden.

Was allrerdings auch geht: Steck alles in eine lib rein und nicht in eine DLL
http://www.pennergame.de/functions/generate_signature_114955.jpg

Wo die Fähigkeiten aufhören ... fängt der Optimismus an

"Unendlichkeit ist der Mangel an Grenzen" Aristoteles

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

3

21.02.2007, 17:37

einfach inlinen klappt bei mir nicht (abgesehen davon das mir das sehr , mhm, dreckig vorkommt).

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
4>C:\Programme\Microsoft Visual Studio 8\VC\include\fstream(802) : error C2248: "std::basic_ios<_Elem,_Traits>::basic_ios": Kein Zugriff auf private Member, dessen Deklaration in der std::basic_ios<_Elem,_Traits>-Klasse erfolgte.
4>        with
4>        [
4>            _Elem=char,
4>            _Traits=std::char_traits<char>
4>        ]
4>        C:\Programme\Microsoft Visual Studio 8\VC\include\ios(151): Siehe Deklaration von 'std::basic_ios<_Elem,_Traits>::basic_ios'
4>        with
4>        [
4>            _Elem=char,
4>            _Traits=std::char_traits<char>
4>        ]
4>        Diese Diagnose trat in der vom Compiler generierten Funktion "std::basic_ofstream<_Elem,_Traits>::basic_ofstream(const std::basic_ofstream<_Elem,_Traits> &)" auf.
4>        with
4>        [
4>            _Elem=char,
4>            _Traits=std::char_traits<char>
4>        ]
Keine Ahnung wie ich an den Fehler komme ehrlich gesagt. Ich kann nur sagen das er in jedem Fall von einem std::ofstream member kommt -_-

Hmm, wenn ich das ganze als Library erstelle ... Dann wird die sozusagen an die kompilierte Exe mit rangehängt? Statisch gelinkt also? Das wäre dann ja eine immerhin halbwegs erfreuliche Option.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

21.02.2007, 18:02

Also ich maches es nur über statische libs und hatte damit auch noch nie Probleme.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

5

21.02.2007, 18:06

Ich neige auch grad langsam zu ner statischen Lib, stelle aber noch etwas merkwürdiges fest ...

Wenn ich versuche meinen Log so zu erstellen:

C-/C++-Quelltext

1
GX::Log myLog = GX::Log("test");
Kommt der oben erwähnte Fehler.

C-/C++-Quelltext

1
GX::Log *myLog = new GX::Log("test");
Haut aber problemlos hin.

Merkwürdig ... Vllt wird bei Verwendung des new operators die Instanz der Klasse irgendwie der DLL überlassen?

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

6

22.02.2007, 10:49

Es scheint das ich meinem Problem nun ein wenig auf die Schliche gekommen bin. Ich habe für jede Klasse nun eine Art Wrapper Finktion erstellt die in etwa so aussieht:

C-/C++-Quelltext

1
2
3
4
Log createLog(std::string name, int mode, std::string seperator)
{
    return(Log(name, mode, seperator));
}
Diese Funktion wird von der DLL aufgerufen (also auch in ihrem Speicherbereich) und nun scheint alles zu gehen.

Ist das etwas mehr oder weniger notwendiges? Gibt es ein Design Pattern oder ähnliches, welchem dieses Verhalten zugrunde liegt? Will mich da mal ein wenig kundig machen ^^ Oder baue ich einfach nur riesigen Müll? ^^

7

22.02.2007, 14:44

Hmm normalerweise gibt es keine Fehlermeldung sondern nur eine Warnung, wenn man STL Klassen innerhalb einer DLL nutzt. Das kann man aber umgehen in dem man die Warnung einfach deaktiviert ... weil sie unwichtig ist oder in dem man den umständlichen Weg wählt und die Templateklassen auch mit exportiert ... dazu gibt es auch was in der MSDN und bei google ... bin für mich zu dem Schluss gekommen die Warnung zu deaktivieren ...
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

22.02.2007, 15:03

Wenn man wirklich Compiler-unabhängig sein will und nicht die Warnungen ignorieren will, dann sollte man die STL nur innerhalb der DLL verwenden und nach außen hin alles kapseln, z.B. mit einer Iterator-Schnittstelle, die dann von einem STL-Iterator implementiert wird (aber davon ist nach außen nichts zu sehen).
Ich habe das zwar noch nicht ausprobiert, aber ich glaube das ist die Lösung, die auch einige Engines wie OGRE verwenden.

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

9

22.02.2007, 15:13

Hui, klingt nach Aufwand *sigh*

Aber mir geht es ja (erstmal) "nur" um std::string, da kann man das Abenteuer ja mal angehen ^^

10

22.02.2007, 15:28

Zitat von »"Nox"«

Also ich maches es nur über statische libs und hatte damit auch noch nie Probleme.


Genauso mache ich das auch, denn ich hatte auch schon Probleme das alles inline zu machen.

@David
Ich bin mir nicht ganz sicher ob das immer 100% klappt, zudem braucht man ja nicht immer einen Iterator, aber ich werd mal schauen ob das so klappt, bin aber ziemlich optimistisch. :D

mfg
http://www.pennergame.de/functions/generate_signature_114955.jpg

Wo die Fähigkeiten aufhören ... fängt der Optimismus an

"Unendlichkeit ist der Mangel an Grenzen" Aristoteles

Werbeanzeige