簡體   English   中英

將SDL2與wxWidgets 3.0一起使用

[英]Using SDL2 with wxWidgets 3.0

我的目標是建立一個Game Boy模擬器。 為此,我想將SDL2表面嵌入到wxWidgets窗口中。

我找到了本教程: http : //code.technoplaza.net/wx-sdl/part1/ ,但是我的程序一運行就會崩潰。 但是我懷疑這是針對SDL1.2的。 該程序的一部分如下所示。

看來,如果我調用SDL_Init()並嘗試顯示wxFrame(在本例中為MainWindow),它將顯示該窗口一秒鍾,然后程序崩潰。 到目前為止,我已經在程序中注釋了所有其他對SDL的調用,因此問題似乎在於在wxFrame上調用Show()並在同一程序中初始化SDL2。

所以問題是:SDL2和wxWidgets 3可以一起工作嗎? 如果沒有,你們可以向我建議Game Boy模擬器的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);

編輯:這是有關如何崩潰的更多信息:在似乎是pthread_mutex_lock反匯編文件的Segfault中崩潰。 這是控制台中帶有堆棧跟蹤的輸出:

Starting /home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx...
The program has unexpectedly finished.
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx crashed

Stack trace:
Error: signal 11:
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx(_ZN5GBEmu7handlerEi+0x1c)[0x414805]
/lib/x86_64-linux-gnu/libc.so.6(+0x36ff0)[0x7fb88e136ff0]
/lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x30)[0x7fb88c12ffa0]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XrmQGetResource+0x3c)[0x7fb88d1ca15c]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XGetDefault+0xc2)[0x7fb88d1a7a92]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x94dcf)[0x7fb88af8edcf]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x97110)[0x7fb88af91110]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(cairo_surface_get_font_options+0x87)[0x7fb88af63e07]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2b61f)[0x7fb88af2561f]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2ef95)[0x7fb88af28f95]

這是似乎失敗的屏幕截圖(第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);



}

您正在遇到一個舊的heisenbug。

解決方法很簡單:您必須在wxWidgets之前(基本上在GTK之前)初始化SDL。 為此,您必須進行更改

wxIMPLEMENT_APP(GBEmu::MainApp);

wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);

這樣wxWidgets不會劫持您的main()。

然后,您必須手動創建main()。 在其中,初始化SDL,然后調用wxEntry():

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);
}

有關該錯誤的更多信息:

我在Google上搜索了一下,發現這些錯誤多年來已經出現在幾個地方。 許多錯誤跟蹤器中都有打開的報告,這些報告的堆棧跟蹤與您在此處獲得的堆棧跟蹤非常相似(帶有調試符號)。

我能找到的最早的報告是cairo bug跟蹤程序( https://bugs.freedesktop.org/show_bug.cgi?id=4373 )的2005(!!)。

我最好的猜測是該錯誤的真正隱藏位置是在GTK,cairo或X中。不幸的是,我目前沒有時間更深入地研究它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM