Ich habe mit SDL ein Spiel programmiert unter Microsoft Visual Studio 2008 C++. Wenn ich auf Release umstelle und neu übersetzte, dann erscheint beim Ausführen der exe Datei folgende Meldung: Unbehandelte Win32-Ausnahme in SDL_Tetris.exe [716]
:
Verschoben durch Admin
da hast du ein Fehler in deinem Quellcode, vermutlich eine nicht initalierte Variable. Das Verhalten ist dann zwischen relase und debug unterschiedlich.
Mein Programm läuft im Release und auch im Debug Mode ohne Probleme. Versteh ich nicht.
Wie kann es denn ohne Fehler laufen wenn diese Fehlermeldung kommt?
Sorry ich hab den Beitrag ausvershen hier reingestellt. Ich weiss auch warum es nicht funktioniert. Sobald ich die sprintf Funktion nicht benutze, dann kann ich auch meine exe Datei ohne Fehlermeldungen starten.
1 | char text_points[50]; |
2 | main() |
3 | {
|
4 | memset(text_points,0,sizeof(text_points[50])); |
5 | ...
|
6 | while(1) |
7 | {
|
8 | ...
|
9 | sprintf(text_points,"Points=%d",points); |
10 | ShowTEXT(text_points,10,270,screen); |
11 | ...
|
12 | }
|
13 | }
|
So wie es aussieht macht diese Funktion probleme:
1 | void ShowTEXT(char *text,int x,int y,SDL_Surface *window) |
2 | {
|
3 | TTF_Font *font; |
4 | font = TTF_OpenFont("arial.ttf", 13 ); |
5 | if (font == NULL) |
6 | {
|
7 | printf("Unable to load font: %s %s \n", "arial.ttf", TTF_GetError()); |
8 | }
|
9 | SDL_Color color = { 240,240,240,0 }; |
10 | SDL_Surface *sText = TTF_RenderText_Solid( font, text, color ); |
11 | SDL_Rect rcDest = { x, y, 0,0 }; |
12 | SDL_BlitSurface( sText,NULL, window, &rcDest); |
13 | }
|
Die Zeile SDL_Surface *sText = TTF_RenderText_Solid( font, text, color ); ist der Übeltäter. Weiss nicht was ich da verbessern könnte.
Hase schrieb: > Die Zeile SDL_Surface *sText = TTF_RenderText_Solid( font, text, color > ); > ist der Übeltäter. Weiss nicht was ich da verbessern könnte. Du könntest zb nicht einfach weitermachen wie bisher, wenn die TTF_OpenFont Funktion NULL zurückgibt. Du könntest zb den Returnwert von TTF_RenderText_Solid daraufhin überprüfen, ob er NULL ist Du könntest zb die Surface, die du von TTF_RenderText_Solid erhältst auch wieder freigeben, nachdem du sie nicht mehr brauchst.
Das hier
1 | char text_points[50]; |
2 | main() |
3 | {
|
4 | memset(text_points,0,sizeof(text_points[50])); |
kannst du dir sparen. Ein simples text_points[0] = '\0'; reicht völlig aus um den String als Leerstring zu markieren. PS: Dir ist hoffentlich auch klar, dass obiges memset nur 1 char, nämlich text_points[0] auf 0 setzt? sizeof(text_points[50]) ist nämlich 1
1 | void ShowTEXT(char *text,int x,int y,SDL_Surface *window) |
2 | {
|
3 | TTF_Font *font; |
4 | font = TTF_OpenFont("arial.ttf", 13 ); |
5 | if (font == NULL) |
6 | {
|
7 | printf("Unable to load font %s \n", TTF_GetError()); |
8 | }
|
9 | SDL_Color color = { 240,240,240,0 }; |
10 | sText = TTF_RenderText_Blended( font, text, color ); |
11 | if(sText == NULL) |
12 | {
|
13 | printf("Error\n"); |
14 | }
|
15 | SDL_Rect rcDest = { x, y, 0,0 }; |
16 | SDL_BlitSurface( sText,NULL, window, &rcDest); |
17 | SDL_FreeSurface(sText); |
18 | }
|
Ich hab nun die Funktion verbessert. Programm läuft aber immer noch nicht an.
du machst nach einem Fehler immer noch weiter als ob nichts passiert ist.
Ich hab nun mal genauer geschaut. Bei der Funktion "TTF_OpenFont" gibt es schon Probleme. Es wird keine Schriftart gefunden. Ich Idiot hab vergessen die arial.ttf Datei in den Release Ordner zu kopieren. Jetzt tut es. Noch eine Sache stört mich aber noch. Ich muss bei mir immer noch die SDL_ttf.dll Datei im Ordner Release mitführen. Was kann man da tun damit man dies nicht mehr tun muss?
Hase schrieb: > Ich hab nun mal genauer geschaut. Bei der Funktion "TTF_OpenFont" gibt > es schon Probleme. Es wird keine Schriftart gefunden. > > Ich Idiot hab vergessen die arial.ttf Datei in den Release Ordner zu > kopieren. Auch. Aber in erster Linie hast du dein Programm so geschrieben, als ob niemals ein Fehler auftreten kann und wenn einer auftritt dann wird so getan als sei er nie passiert (die Ausgabe der Fehlermeldung ist zwar löblich, aber danach so weiterzumachen als ob nichts passiert sei ist es eben nicht. Was bringt es dir einen Fehler zu erkennen, wenn du danach einfach weitermachst?)
1 | void ShowTEXT(char *text,int x,int y,SDL_Surface *window) |
2 | {
|
3 | TTF_Font *font; |
4 | font = TTF_OpenFont("arial.ttf", 13 ); |
5 | if (font == NULL) |
6 | {
|
7 | printf("Unable to load font %s \n", TTF_GetError()); |
8 | return; |
9 | }
|
10 | |
11 | SDL_Color color = { 240,240,240,0 }; |
12 | sText = TTF_RenderText_Blended( font, text, color ); |
13 | if(sText == NULL) |
14 | {
|
15 | printf("Error\n"); |
16 | return; |
17 | }
|
18 | |
19 | SDL_Rect rcDest = { x, y, 0,0 }; |
20 | SDL_BlitSurface( sText,NULL, window, &rcDest); |
21 | SDL_FreeSurface(sText); |
22 | }
|
Ok, Dies bedeutet, dass bei einem Fehler das Programm beendet werden soll oder? Zum Beispiel mit einem assert.
Hase schrieb: > Ok, Dies bedeutet, dass bei einem Fehler das Programm beendet werden > soll oder? Das musst du entscheiden. Aber wenn deine Font-lade Funktion meldet, dass es den Font nicht finden kann, dann wird es wohl wenig Sinn haben, mit dem nicht geladenen Font eine Textausgabe zu machen. Wenn der Font nicht da ist, kann man auch keine Ausgabe machen. Damit kommt dann zwar kein Text auf den Bildschirm, aber das ist immer noch besser als ein Absturz. > Zum Beispiel mit einem assert. Nein. Im einfachsten Fall: nichts tun. Wenn irgendwie möglich, den Benutzer auf das Problem aufmerksam machen. Aber eines darf ein Programm niemals: Egal was passiert, es darf nicht abstürzen!
Hase schrieb: > Ok, Dies bedeutet, dass bei einem Fehler das Programm beendet werden > soll oder? Ja. Am besten mit ausführlicher Fehlermeldung. > Zum Beispiel mit einem assert. Nein, assert hat im Release nichts verloren.
Meine Quellen (kurzes Googeln) sprechen sich auch nicht darüber aus, was passiert, wenn man denselben Font ein 2-tes mal lädt. Bekommt man dan denselben Pointer wie beim ersten mal oder betreibt die darunterliegende Schicht kein Caching? Wird ein Font 100000 mal geladen, hat man ihn dann 100000 mal im Speicher? Muss man ihn jedesmal freigeben? Warum muss eigentlich bei jeder Textausgabe der Font immer wieder neu geladen werden - ist doch eh jedesmal derselbe Font; kann man sich den nicht einfach aufheben? Fragen über Fragen.
Sven P. schrieb: > Hase schrieb: >> Ok, Dies bedeutet, dass bei einem Fehler das Programm beendet werden >> soll oder? > Ja. Am besten mit ausführlicher Fehlermeldung. Ich kenne SDL nicht. Aber in einem GUI Programm sollte IMHO eine Message Box hochpappen mit der Fehlermeldung. Automatische Beendigung ist immer so eine Sache.
Was müsste ich genau tun, damit ich die SDL_ttf.dll nicht immer im Release Ordner kopieren muss?
Hase schrieb: > Was müsste ich genau tun, damit ich die SDL_ttf.dll nicht immer im > Release Ordner kopieren muss? Das ist das Wesen einer DLL. Aber du kannst ja mal nachsehen, ob es die SDL auch als statische Library gibt. Dann linkst du sie mit zum EXE dazu und musst sie nicht mitgeben. (Aber gewöhn dich daran, dass heutzutage ein EXE aus mehreren DLL besteht, die alle mit dem Programm mitgeliefert werden müssen. Du musst ja auch das Font-File mitliefern)
> Du musst ja auch das Font-File mitliefern
Eigentlich nicht, denn das erledigt schon das Betriebssystem.
Ich hab mir nun SDL nicht näher angesehen, aber sind dessen
Fontbehandlungsfunktionen nicht in der Lage, auf die vom Betriebssystem
verwendeten Schriftarten zuzugreifen?
Sollten sie es nicht sein, kann arial.ttf immer im Verzeichnis
%systemroot%\fonts gefunden werden. systemroot ist eine
Environmentvariable, die z.B. "c:\windows" enthält, oder wie das
Windows-Installationsverzeichnis auch immer heißt.
Rufus t. Firefly schrieb: > Eigentlich nicht, denn das erledigt schon das Betriebssystem. > Ich hab mir nun SDL nicht näher angesehen, aber sind dessen > Fontbehandlungsfunktionen nicht in der Lage, auf die vom Betriebssystem > verwendeten Schriftarten zuzugreifen? Keine Ahnung. Aber anscheinend nicht. Sonst hätten sie den Font auch bei seinen Tests gefunden.
Naja, es könnte ja eine Alternativ-Variante der Funktion TTF_OpenFont() geben, der statt eines Dateinamens nur der Fontname übergeben werden muss ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.