Ich versuche, SDL_ttf in ein Partikelgenerator-Programm zu integrieren, das ich vor kurzem geschrieben habe, aber ich bekomme immer einen Laufzeitfehler: Access violation reading location 0x00000044.
. Dies geschieht, wenn ich versuche, eine Textoberfläche auf dem Spielbildschirm zu blitten. Ich habe meinen Code mehrere Male durchsucht und hatte ähnliche Probleme in der Vergangenheit, aber ich kann das Problem nicht herausfinden. Was ist das wahrscheinlichste Problem?Warum erhalte ich einen Zugriffsverletzungsfehler, wenn ich Text mit SDL2_ttf blitze?
Der Fehler tritt in Text.h:
#pragma once
#include "System.h"
#include <iostream>
#include <sstream>
class Text {
public:
Text(const char *fontaddress = "times.ttf", int size = 30, const char
*begintext = "0", int x = 0, int y = 0, SDL_Color color = { 255, 255, 255 }) {
font = TTF_OpenFont(fontaddress, size);
drawpos.x = x;
drawpos.y = y;
textcolor = color;
text = TTF_RenderText_Solid(font, begintext, textcolor);
if (!text)
std::cout << "damn" << std::endl;
}
~Text() {
if (text)
SDL_FreeSurface(text);
TTF_CloseFont(font);
}
void SetText(const char *txt);
void SetText(int txt);
void DrawText();
private:
TTF_Font *font;
SDL_Rect drawpos;
SDL_Color textcolor;
SDL_Surface *text;
};
inline void Text::SetText(const char *txt) {
if (text)
SDL_FreeSurface(text);
text = TTF_RenderText_Solid(font, txt, textcolor);
}
inline void Text::SetText(int txt) {
if (text)
SDL_FreeSurface(text);
std::stringstream s;
s << txt;
text = TTF_RenderText_Solid(font, s.str().c_str(), textcolor);
}
inline void Text::DrawText() {
static SDL_Surface *const screen = System::GetInstance().GetScreen();
SDL_BlitSurface(text, NULL, screen, &drawpos);
//^This line throws the exception
}
bar.h:
#pragma once
#include <SDL.h>
#include <iostream>
#include "System.h"
#include "Text.h"
class Bar {
public:
Bar(const int xpos = 0, const int ypos = 0, unsigned width = 0, unsigned height = 0, const Uint32 c = SDL_MapRGB(System::GetInstance().GetScreen()- >format, 0, 0, 0), const char *address = "times.ttf",
int sz = 30, const char *bgtext = "0", SDL_Color co = { 255, 255, 255 }) : max_w(width), color(c), colortext(address, sz, bgtext, xpos - 50, ypos, co) {
bar.x = xpos;
bar.y = ypos;
bar.w = width;
bar.h = height;
modval = max_w/255;
if (!modval)
modval = 1;
if (max_w < 255) {
std::cerr << "invalid width; below 255" << std::endl;
}
colorval = width/modval;
}
void Modify(int width_modifier);
void Draw();
Uint8 GetColorVal();
private:
SDL_Rect bar;
unsigned max_w;
Uint32 color;
Uint8 modval; // number of pixels (in width) required to advance or decrement the color value by 1
Uint8 colorval; // the color value modified when width is changed. Determined by
// modval. This value will be used by RGBTable class for text (on-screen value display) and particle color creation
Text colortext;
};
//inlined methods
//modifies the width of a bar
inline void Bar::Modify(int width_modifier) {
if (bar.w + width_modifier < 0 || bar.w + width_modifier > max_w)
return;
bar.w += width_modifier;
if (bar.w % modval == 0) {
colorval = bar.w/modval;
colortext.SetText(colorval);
}
}
//draws bar to system screen
inline void Bar::Draw() {
static SDL_Surface *screen = System::GetInstance().GetScreen();
SDL_FillRect(screen, &bar, color);
colortext.DrawText();
}
//returns the 8bit color value represented by the width of a bar
inline Uint8 Bar::GetColorVal() {
return colorval;
}
ColorTable.h:
#pragma once
#include "System.h"
#include "Bar.h"
#include <array>
class ColorTable {
public:
static bool needupdate;
static ColorTable &GetInstance();
void Input();
void Draw();
Uint32 MakeColor();
private:
ColorTable(int top_left_x, int top_left_y, unsigned width, int height, int sepval) {
static SDL_Surface *screen = System::GetInstance().GetScreen();
bars[0] = Bar(top_left_x, top_left_y, width, height, SDL_MapRGB(screen->format, 255, 0, 0));
bars[1] = Bar(top_left_x, top_left_y + height + sepval, width, height, SDL_MapRGB(screen->format, 0, 255, 0));
bars[2] = Bar(top_left_x, top_left_y + (sepval *2) + (height * 2), width, height, SDL_MapRGB(screen->format, 0, 0, 255));
activebar = bars.begin();
}
std::array<Bar, 3> bars;
std::array<Bar, 3>::iterator activebar;
const Uint8 *key = SDL_GetKeyboardState(NULL);
};
inline ColorTable &ColorTable::GetInstance() {
static ColorTable table(750, 620, 510, 50, 10);
return table;
}
inline void ColorTable::Draw() {
bars[0].Draw();
bars[1].Draw();
bars[2].Draw();
}
inline Uint32 ColorTable::MakeColor() {
static SDL_Surface *screen = System::GetInstance().GetScreen();
Uint8 r = bars[0].GetColorVal();
Uint8 g = bars[1].GetColorVal();
Uint8 b = bars[2].GetColorVal();
return SDL_MapRGB(screen->format, r, g, b);
}
Nach dem Erstellen von 'text' mit' TTF_RenderText_Solid' sollten Sie überprüfen, ob 'text' erfolgreich erstellt wurde, indem Sie' if (text) ... 'ausführen. 'TTF_RenderText_Solid' gibt' null' zurück, wenn die Erstellung fehlschlägt, und das würde die Zugriffsverletzung erklären: versuchen, von Null zu lesen – Chara
@Chara Ich habe es versucht; Ich habe die Gültigkeit von 'text' überall dort überprüft, wo sein Zustand verändert wurde, sowie vor Funktionsaufrufen zu' SDL_BlitSurface'. Die Ausnahme wird immer noch vom selben Aufruf ausgelöst. Weißt du etwas anderes, das das Problem sein könnte? – CornOnTheMacabre