C++ 将SDL2与wxWidgets 3.0结合使用

C++ 将SDL2与wxWidgets 3.0结合使用,c++,sdl,wxwidgets,C++,Sdl,Wxwidgets,我的目标是建立一个游戏机模拟器。为了做到这一点,我想将SDL2曲面嵌入wxWidgets窗口 我找到了这个教程:,但我的程序一运行就崩溃了。然而,我怀疑这是针对SDL1.2的。部分程序如下所示 似乎如果我调用SDL_Init()并尝试显示wxFrame(在本例中,它是MainWindow),它会显示窗口一秒钟,然后程序崩溃。到目前为止,我在程序中注释了所有其他对SDL的调用,因此问题似乎在于在wxFrame上调用Show()并在同一程序中初始化SDL2 所以问题是:SDL2和wxWidgets

我的目标是建立一个游戏机模拟器。为了做到这一点,我想将SDL2曲面嵌入wxWidgets窗口

我找到了这个教程:,但我的程序一运行就崩溃了。然而,我怀疑这是针对SDL1.2的。部分程序如下所示

似乎如果我调用SDL_Init()并尝试显示wxFrame(在本例中,它是MainWindow),它会显示窗口一秒钟,然后程序崩溃。到目前为止,我在程序中注释了所有其他对SDL的调用,因此问题似乎在于在wxFrame上调用Show()并在同一程序中初始化SDL2

所以问题是:SDL2和wxWidgets 3可以一起工作吗?如果不是,你们能给我推荐一个游戏机模拟器的GUI吗?wxWidgets是否像Qt一样有自己的图形框架(我宁愿避免Qt)

非常感谢

#include "MainApp.h"
#include "MainWindow.h"

#include <stdexcept>

namespace GBEmu {


static void initSDL() {

    //This and SDL_Quit() are the only calls to the SDL library in my code
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
       throw std::runtime_error("Fatal Error: Could not init SDL");
    }
}


bool MainApp::OnInit()
{
    try {
        //If I comment out this line, the MainWindow wxFrame shows up fine.
        //If I leave both uncommented, the window shows up quickly and then 
        //crashes.
        initSDL();


        //If I comment out this line and leave initSDL() uncommented,
        //the program will not crash, but just run forever.
        (new MainWindow("GBEmu", {50,50}, {640,480}))->Show(); 


    } catch(std::exception &e) {
        wxLogMessage(_("Fatal Error: " + std::string(e.what())));
    }

    return true;
}

int MainApp::OnExit() {
    SDL_Quit();

    return wxApp::OnExit();
}


}


wxIMPLEMENT_APP(GBEmu::MainApp);
这是它似乎失败的地方的屏幕截图(第7行):

更新:在我的MainWindow类中,我在窗口上附加了一个菜单栏。然而,当我对菜单栏的设置进行注释时,即使初始化了SDL,窗口也会显示得很好。如果已注释掉initSDL(),但未注释菜单栏的设置,则菜单栏将显示良好。这里是我设置菜单栏的地方:

MainWindow::MainWindow(const wxString &title, const wxPoint &pos, const wxSize &size)
    :wxFrame(nullptr, wxIDs::MainWindow, title, pos, size){

  wxMenu *fileMenu = new wxMenu;
    fileMenu->Append(wxID_EXIT);

    wxMenuBar *menuBar = new wxMenuBar;

    menuBar->Append(fileMenu, "&File");

    //commenting this line out will allow the window to showup
    //and not crash the program
    SetMenuBar(menuBar);



}

你正在经历一个老海森堡

解决方法很简单:必须在wxWidgets之前初始化SDL(基本上是在GTK之前)。要做到这一点,你必须改变

wxIMPLEMENT_APP(GBEmu::MainApp);

这样wxWidgets就不会劫持main()

然后必须手动创建main()。在其中,初始化SDL,然后调用wxEntry():

int main(int argc,char**argv)
{
if(SDL_Init(SDL_Init_EVERYTHING)<0)
{

std::cerr它是如何崩溃的?即堆栈跟踪是什么?我在最近的编辑中添加了此信息。还要注意的是,我似乎已将问题缩小到菜单栏的设置(如编辑中所示。谢谢!调用
SetMenuBar()可能导致的唯一更改
是因为您收到了一个额外的调整大小事件,因此在尝试重新绘制窗口时可能会发生一些不好的情况。没有符号,崩溃堆栈的信息量不大,因此我很难说更多。。。
wxIMPLEMENT_APP(GBEmu::MainApp);
wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);
int main(int argc, char** argv)
{
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        std::cerr << "Could not initialize SDL.\n";
        return 1;
    }

    return wxEntry(argc, argv);
}