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

1

15.12.2010, 20:28

Problem mit DLL und STL

Hi Leute,

ich wollte mir mal eine DLL mit Funktionen/Klassen erstellen, die ich immer wieder brauche. Soweit so gut.
Unter anderem habe ich z.B. eine Klasse, mit der ich mit wenig Aufwand etwas in eine Datei schreiben kann.

Eine Funktion einer Klasse sieht z.B. so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
bool CFile::WriteToFile (float fValue, std::string FileName, std::string Text)
{
    output.open (FileName, std::ios::app); // <- std::ofstream
    stream << fValue; // <- std::ostringstream
    Text = Text + " " + stream.str (); 

    output.write (Text.c_str (), sizeof (Text));  
        output.close (); 

    return true; 
}


So, lässt sich auch alles komplilieren, allerdings erscheint mehrmals diese Warnung

Laut MSDN kann ich diese Warnung ja ignorieren, wenn ich die STL benutze und die Fehler im Zusammenhang mit dieser auftreten.

Habe ich dann auch gemacht und meine Funktion einfach mal getestet.
Jedenfalls erscheint in der .txt dann nur kaka^^

Sieht aus wie hunderte eckige 0en.
Wenn ich nur text rein schreibe (andere Funktion nur ohne den sstream), ist die erste Spalte in der txt der korrekte string, aber weiter rechts in anderen Spalten stehen einige seltsame Zeichen.
Habe zur Verdeutlichung noch 2 Screens angehangen.

Ich habe dann versucht den Code der Funktion in meiner Testanwendung direkt zu testen, also ohne die DLL.
Das gibt aber ähnlich schöne Ergebnisse.

Der String ist aber bis kurz vor dem schreiben in die Datei noch korrekt, habe ihn mit cout überprüft.
Ich bin jetzt etwas verwirrt warum das nicht klappt, auch wenn ich es direkt implementiere.

lg chaia
»Chaia*« hat folgende Bilder angehängt:
  • Seltsam.jpg
  • Null.jpg

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Chaia*« (15.12.2010, 21:12)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

15.12.2010, 21:31

Überleg mal was sizeof(Text) ist. Abgesehen davon frag ich mich gleich mehrere Dinge:
  1. Warum muss sowas in eine dll?
  2. Warum der stringstream?
  3. Warum dann nicht gleich die ganze Formatierung mit dem stringstream machen?
  4. Warum output.write?
Und vielleicht als kleine Anmerkung: std:: Typen in einem dll Interface zu haben ist eine Sache die sehr schnell sehr schmerzhaft enden kann z.B. weil es schnell mal passiert ist dass die dll eine andere Laufzeitbibliothek linked als die exe was dann sofort in die Hose geht. Von unterschiedlichen Compilern gar nicht zu reden, dann funktioniert sowieso gar nix mehr...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (15.12.2010, 21:36)


n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

3

15.12.2010, 21:37

Also zum einen musst du beachten, dass es ja sowas wie eine Codierung gibt. Möglicherweise kannst du die Daten korrekt (im Sinne deines Programms) in die Datei schreiben, und diese dann auch korrekt wieder auslesen. Dass aber ein externes Textprogramm, wie z.B. Word oder sonstwas damit irgendwas anfangen kann, muss nicht sein. Das kannst du dir vor allem bei Floats klarmachen. Alles im Rechner sind ja nur 1en und 0en. Eine Gleitkommazahl z.B. nach dem IEEE 754 Standard ist auch nichts weiteres als eine Folge von 1en und 0en, die auf ganz bestimmte Art und weise vom prozessor behandelt wird. Wenn du das ganze binär in eine Datei schreibst, woher soll dann ein externes Programm wissen, dass es eine Gleitkommazahl sein soll, wenn es genau so gut auch ein Integer sein könnte. Gleiches gilt auch für die Kodierung von Strings. An sowas musst du also immer denken, es sei denn, du liest es mit deinem eigenen Programm auf deinem eigenen Rechner wieder aus.

Ansonsten habe ich mit Strings in C++ auch selbst noch so meine Probleme. Ich denke aber, dass das hier:

C-/C++-Quelltext

1
output.write (Text.c_str (), sizeof (Text));

nicht so viel Sinn, denn du willst ja eigentlich die Daten in der Länge des Textes schreiben, und nicht in der Länge der Klasse std::string ^^

PS: Diese eckigen Nullen sind normalerweise Platzhalter, wenn ein Zeichen nicht erkannt wird.

4

15.12.2010, 22:05

@ dot

1. Ist ja nicht nur das, was da drin ist, habe wie gesagt vor, alle meine Klassen/Funktionen, die allgemein gehalten sind und die ich immer wieder brauche, dort rein zu packen. Dann muss ich nicht immer meine ganzen header einbinden, sondern nur 1 lib linken und dann die dll dazupacken. Ich finde es so angenehmer. Das ganze in eine statische lib packen wollte ich nicht, da wird die exe irgendwann recht groß.
2. Naja um die Zahl in den String einzubinden. Der Text, der übergeben wird, ist nur optional, wenn nichts angeben wird, ist er "", also nichts. Hatte mir das so gedacht, dass man evtl. noch einen Kommentar zu dieser Zahl ausgeben möchte (falls ich es z.B. als Logbuch o.ä. verwende). Welche Möglichkeiten gäbe es da noch, eine Variable Zahl in einen String einzubinden? Ich dachte mit stringstreams ginge das schön einfach, habe es bis jetzt immer so gemacht, falls ich etwas derartiges gebraucht habe.
3. Stimmt, da hast du recht, wäre einfacher.
4. Wie schreibt man sonst etwas mit ofstreams in eine Datei? Mit write() bin ich immer gut gefahren, wird ja z.B. auch in "C++ für Sppro." so gemacht.

Das heißt ich soll gar keine Dinge aus der STL benutzen? Das macht die ganze Sache natürlich schon recht umständlich...
Habe aber beim googlen nach meinem Problem öfters gelesen, dass Leute die STL in ihren dlls verwenden, warum kracht es dann nicht ständig?

@ no one

Bis jetzt hat es immer geklappt die Daten, die ich z.B. in eine txt geschrieben habe auch korrekt zu lesen (mit Editor z.B.).
Damit die Daten in binär Form da drin landen müsste ich doch das Flag ios::binary angeben oder?

Mit sizeof(Text) habt ihr natürlich recht, etwas dumm von mir^^ Richtig müsste es dann Text.size() heißen oder? Das gibt doch die größe in Bytes des Strings zurück, wenn ich mich nicht irre.

Entschuldigt, dass ich so viele Fragen stelle, kenne mich mit der STL noch nicht so richtig aus.

lg chaia

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

15.12.2010, 22:34

Welche Möglichkeiten gäbe es da noch, eine Variable Zahl in einen String einzubinden? Ich dachte mit stringstreams ginge das schön einfach, habe es bis jetzt immer so gemacht, falls ich etwas derartiges gebraucht habe.

Naja dein file ist bereits ein stream, deswegen könntest du auch einfach direkt reinschreiben:

C-/C++-Quelltext

1
2
3
4
5
6
bool CFile::WriteToFile (float fValue, std::string FileName, std::string Text)
{
    std::ofstream output(FileName.c_str(), std::ios::app);
    output << Text << ' ' << fValue;
    return true; 
}


;)
Dein ursprünglicher Code hatte übrigens vermutlich noch das Problem dass dein stringstream seinen Inhalt über mehrere Funktionsaufrufe behalten hätte, was vermutlich nicht ganz deiner Absicht enspricht!?

Das heißt ich soll gar keine Dinge aus der STL benutzen? Das macht die ganze Sache natürlich schon recht umständlich...

Nein, ich wollte dich nur drauf aufmerksam machen dass das unter Umständen schnell problematisch wird. Die Tatsache dass das Exportieren von Klassen in dlls sowieso nur von Microsoft Compilern unterstützt wird grenzt das Ganze natürlich ein.

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

6

15.12.2010, 23:30

Nein, ich wollte dich nur drauf aufmerksam machen dass das unter Umständen schnell problematisch wird. Die Tatsache dass das Exportieren von Klassen in dlls sowieso nur von Microsoft Compilern unterstützt wird grenzt das Ganze natürlich ein.
Ich hab noch nie was in eine dll exportieren müssen, deshalb hab ich keine ahnung davon. Was genau meinst du mit: exportieren von klassen in dlls geht nur mit microsoft compilern?
Ich hab schon fast immer mit GCC gearbeitet und schon jede menge verschiedener bibliotheken verwendet, die dann natürlich auch alle damit compiled werden mussten... hatte mit den dlls da aber nie probleme? OGRE z.B. wäre ein beispiel, und das hat ja auch so die ein oder andere klasse ^^

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

15.12.2010, 23:36

Was genau meinst du mit: exportieren von klassen in dlls geht nur mit microsoft compilern?

Genau das. Dlls unterstützen nur einfache Funktionen. Das Exportieren von kompletten Klassen ist ein Microsoft-spezifisches Feature.

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

8

16.12.2010, 00:11

Und wieso geht es mit GCC dann auch? bzw. was genau soll denn nicht funktionieren?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

16.12.2010, 00:18

Unterstützt GCC denn __declspec(dllexport). Das wusste ich tbh nicht, ist aber auch egal ich bin mir sicher dass der GCC natürlich etwas vergleichbares hat. Der Punkt ist aber dass sowas immer eine rein compilerspezifische Angelegenheit ist. Wenn du mit dem GCC eine dll erstellst in die eine Klasse exportiert wurde dann wirst du diese mit MSVC nicht benutzen können und umgekehrt...

10

16.12.2010, 00:24

Ich will erstmal sehen, dass der gcc überhaupt eine dll erstellt :D Dll ist eine rein Windows spezifische Sache. Der gcc kann dynamische Bibliotheken, aber auch nur die für Linux typische Variante (übrigens ohne spezielles Codewort für den Export, es werden alle Funktionen/Globale Variablen exportiert). Dynamische Bibliotheken sind für C/C++ sowieso, überhaupt und immer rein Plattform und Compilerspezifisch, da keiner seiner Standards diese definiert.

Werbeanzeige