ImGui + SDL2 - ImGui 初始化时出现 SIGILL 错误

问题描述 投票:0回答:1

我正在为 NES 编写一个简单的模拟器。我正在尝试将 SDL2 用于图形,并使用 ImGui (SDL 渲染器,不一定限于它)。

这一切都适用于 github 上的相应示例,直到我进行了一些重构并移动了与其自己的类相关的所有图形。

现在程序无法启动,并在 ImGui_ImplSDLRenderer2_Init(renderer); 上抛出

SIGILL 错误
(代码 -1073741795)。如果我将其注释掉,则错误会在其前面抛出一行,即
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);

调试错误表明,当两个函数之一尝试调用

ImGui::GetIO()
时,会发生错误。我尝试了一切,但似乎没有任何效果。

这是我的代码。

图形.h

#include "imgui.h"
#include "imgui_memory_editor.h"
#include "imgui_impl_sdl2.h"
#include "imgui_impl_sdlrenderer2.h"

#include <SDL.h>

struct WindowSettings {
    explicit WindowSettings(const char *title, int width, int height, bool use_default = true);
    
    SDL_WindowFlags window_flags;
    SDL_RendererFlags renderer_flags;
    ImGuiConfigFlags_ imgui_flags;
    
    int width, height;
    
    const char* title;
};

class Window {
public:
    Window(WindowSettings *settings);
    ~Window();
    
    int init();
    void quit();
    
    bool poll_events();
    bool should_close() { return event.type == SDL_QUIT || (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)); }
    
    void start_imgui_frame();
    void render();
    
    void set_background_color(float r, float g, float b, float a) { background = {r, g, b, a}; }
    
private:
    WindowSettings *settings;
    
    SDL_Window *window;
    SDL_Renderer *renderer;
    ImGuiIO *io;
    
    SDL_Event event;
    
    ImVec4 background = {58, 58, 77, 255};
};

图形.cpp

#include "Graphics.h"

WindowSettings::WindowSettings(const char *title, int width, int height, bool use_default) {
    this->title = title;
    
    this->width = width;
    this->height = height;
    
    if (!use_default) return;
    
    window_flags = (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI);
    renderer_flags = (SDL_RendererFlags)(SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
    
    imgui_flags = ImGuiConfigFlags_NavEnableKeyboard;
}

Window::Window(WindowSettings *settings) {
    this->settings = settings;
    
    window = nullptr;
    renderer = nullptr;
}

Window::~Window() {
    quit();
}

void Window::quit() {
    ImGui_ImplSDLRenderer2_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

int Window::init() {
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
        printf("Error: %s\n", SDL_GetError());
        return -1;
    }

    window = SDL_CreateWindow(settings->title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, settings->width, settings->height, settings->window_flags);
    if (window == nullptr) {
        printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
        return -1;
    }
    renderer = SDL_CreateRenderer(window, -1, settings->renderer_flags);
    if (renderer == nullptr) {
        SDL_Log("Error creating SDL_Renderer!");
        return 0;
    }

    SDL_RendererInfo info;
    SDL_GetRendererInfo(renderer, &info);
    SDL_Log("Current SDL_Renderer: %s", info.name);

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    io = &ImGui::GetIO(); (void)io;
    io->ConfigFlags |= settings->imgui_flags;
    
    ImGui::StyleColorsDark();
    
    ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
    ImGui_ImplSDLRenderer2_Init(renderer); // Error line
}

bool Window::poll_events() {
    if (SDL_PollEvent(&event)) {
        ImGui_ImplSDL2_ProcessEvent(&event);
        return true;
    }
    
    return false;
}

void Window::start_imgui_frame() { // NOLINT(*-convert-member-functions-to-static)
    ImGui_ImplSDLRenderer2_NewFrame();
    ImGui_ImplSDL2_NewFrame();
    ImGui::NewFrame();
}

void Window::render() {
    ImGui::Render();
    SDL_RenderSetScale(renderer, io->DisplayFramebufferScale.x, io->DisplayFramebufferScale.y);

    SDL_SetRenderDrawColor(renderer, (Uint8)background.x, (Uint8)background.y, (Uint8)background.z, (Uint8)background.w);
    SDL_RenderClear(renderer);

    ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), renderer);
    SDL_RenderPresent(renderer);
}

main.cpp

#include "imgui.h"
#include "imgui_memory_editor.h"
#include "imgui_impl_sdl2.h"
#include "imgui_impl_sdlrenderer2.h"

#include <SDL.h>

#include "Cpu.h"
#include "Graphics.h"

int main(int, char**)
{
    WindowSettings settings("NesMu - alpha1.0.0", 800, 800);
    Window *win = new Window(&settings);
    win->init();
    
    uint8_t program[] = {0XA9, 0XC0, 0XAA, 0XE8, 0X00};
    CPU cpu;
    cpu.set_demo(program);
    bool end = false;
    
    static MemoryEditor prog_editor;
    prog_editor.ReadOnly = true;

    // Main loop
    bool done = false;
    while (!done)
    {
        while (win->poll_events())
        {
            if (win->should_close()) done = true;
        }
        
        win->start_imgui_frame();

        {
            ImGui::Begin("CPU Registers");
            
            ImGui::Text("PC: %04X", cpu.getPC());
            ImGui::Text("A: %02X", cpu.getA());
            ImGui::Text("X: %02X", cpu.getX());
            ImGui::Text("Y: %02X", cpu.getY());
            ImGui::Text("SP: %02X", cpu.getSP());
            ImGui::Text("Flags: %08p", cpu.getFlags());
            
            if (ImGui::Button("Step", {60, 20}) && !end) end = cpu.step();
            ImGui::SameLine();
            if (ImGui::Button("Reset", {60, 20})) { cpu.reset(); end = false; }
            
            ImGui::End();
        }

        strcpy(reinterpret_cast<char *>(program), reinterpret_cast<const char *>(cpu.getDemo()));
        prog_editor.DrawWindow("Program memory", program, sizeof(program));
        prog_editor.GotoAddrAndHighlight(cpu.getPC(), cpu.getPC() + 1);
        
        win->render();
    }
    
    win->quit();
    
    return 0;
}

有人可以帮助我吗?

编辑1 这里要求的是汇编指令和完整的调用堆栈。 这似乎是指令:

ud2

根据调用堆栈,Clion 只让我检索当前线程的堆栈。在这里:

Window::init Graphics.cpp:67
SDL_main main.cpp:15
c++ sdl-2 imgui
1个回答
0
投票

解决方案: 当我决定在 Clion 中设置 WSL 工具链后,C++ 编译器警告我在 Window::init() 函数中存在

缺少 return 语句

在最后添加了声明,一切又开始按预期进行。

我仍然不知道为什么 g++ 和 gcc 都没有警告我这一点。

感谢所有试图帮助我的人。

© www.soinside.com 2019 - 2024. All rights reserved.