c - 为什么函数 SDL_WaitEvent (SDL2) 在我的代码中出现错误?

标签 c events sdl sdl-2

我正在处理 Wolf,我遇到了一个错误,有时被检测为段错误,有时被检测为 sig 中止,有时我们也收到此错误:“线程已经初始化此类!”

我使用了lldb,他显示WaitEvent函数出错了。 SDL_Event 事件;是由这个函数初始化的,有些我不明白我怎么会出错。

int     main(int ac, char **av)
{

    int             fd;
    t_var           var;
    t_player        player;

    ft_init_sdl(&var);
    init_key_move(&var); // int attribution
    if (ac != 2 || (fd = open(av[1], O_RDONLY)) < 0)
        exit(EXIT_FAILURE);
    parsing_map(fd, &var); // map parsing 
    var.m = fill_map_struct(var); // map parsing again
    player_data_set(&player, &var); // int atribution for the player
    open_wall_texture(&var); //loading texture form bmp with SDL_LoadBPM
    open_img_opt_button(&var); // same
    display(&var, &player); // displaying the game
    return (0);
}

    void    ft_init_sdl(t_var *var)
    {
        var->sdl.window = NULL;
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
            return ;
        var->sdl.window = SDL_CreateWindow("WOLFCRAFT", SDL_WINDOWPOS_CENTERED, \
                SDL_WINDOWPOS_CENTERED, SIZE_X, SIZE_Y, 0);
        var->sdl.render = SDL_CreateRenderer(var->sdl.window, -1, 0);
        if (!var->sdl.window || !var->sdl.render)
            return ;
    }

void    display_3(t_var *var, t_player *pl)
{
    if (var->sdl.event.type == SDL_QUIT)
        ft_clean_quit(var->sdl.render, var->sdl.window);
    else if (var->sdl.event.key.keysym.sym == SDLK_ESCAPE)
        ft_clean_quit(var->sdl.render, var->sdl.window);
    else if (var->sdl.event.type == SDL_KEYDOWN && var->menu_is_act == 1)
        ft_move(var->sdl.event.key.keysym.sym, pl, var->sdl.render, var);
    if (var->sdl.event.type == SDL_MOUSEMOTION && (var->menu_is_act == 1))
    {
        var->on = 1;
        menu_button_in_game(var, pl);
    }
    else if (var->sdl.event.type == SDL_MOUSEBUTTONDOWN \
                    && (var->menu_is_act == 1))
    {
        var->on = 0;
        menu_button_in_game(var, pl);
    }
}

void    display_2(t_var *var, t_player *pl, int *token)
{
    init_var_display(var, token);
    ft_menu(var, pl);
}

void    display(t_var *var, t_player *pl)
{
    int token;

    display_2(var, pl, &token);
    while (SDL_WaitEvent(&var->sdl.event))
    {
        if (var->sdl.event.type == SDL_MOUSEMOTION \
                && (var->menu_is_act == 0 || var->menu_is_act == 2))
        {
            var->on = 1;
            ft_menu(var, pl);
        }
        else if (var->sdl.event.type == SDL_MOUSEBUTTONDOWN \
                        && (var->menu_is_act == 0 || var->menu_is_act == 2))
        {
            var->on = 0;
            ft_menu(var, pl);
        }
        else
            display_3(var, pl);
        if (var->menu_is_act == 2)
        {
            change_key(var, pl);
            choose_key(var, pl);
        }
    }
}

我们花了一周时间寻找解决方案,但一无所获。

谢谢。

这是 lldb 用“bt”向我显示的内容。

Process 53017 launched: '/Users/vgauther/Desktop/work/wolf3d' (x86_64)
Process 53017 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x00007fff542b22ce libobjc.A.dylib`_class_initialize + 37
libobjc.A.dylib`_class_initialize:
->  0x7fff542b22ce <+37>: movq   0x20(%r14), %rax
    0x7fff542b22d2 <+41>: movq   %rax, %rcx
    0x7fff542b22d5 <+44>: andq   %rbx, %rcx
    0x7fff542b22d8 <+47>: movq   0x8(%rcx), %rcx
Target 0: (wolf3d) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x00007fff542b22ce libobjc.A.dylib`_class_initialize + 37
    frame #1: 0x00007fff542b1e8f libobjc.A.dylib`lookUpImpOrForward + 228
    frame #2: 0x00007fff542b1914 libobjc.A.dylib`_objc_msgSend_uncached + 68
    frame #3: 0x00007fff2a5696b6 AppKit`-[NSTextFieldCell _allowsVibrancyForControlView:] + 394
    frame #4: 0x00007fff2a557871 AppKit`-[NSControl allowsVibrancy] + 49
    frame #5: 0x00007fff2a55782a AppKit`-[NSView(NSInternal) _needsVibrancy] + 83
    frame #6: 0x00007fff2a55766d AppKit`-[NSView(NSInternal) _updateVibrancy] + 26
    frame #7: 0x00007fff2a674a25 AppKit`-[NSView viewWillDraw] + 87
    frame #8: 0x00007fff2adeb6cf AppKit`_NSViewWillDraw + 45
    frame #9: 0x00007fff2a674e21 AppKit`-[NSView viewWillDraw] + 1107
    frame #10: 0x00007fff2adeb6cf AppKit`_NSViewWillDraw + 45
    frame #11: 0x00007fff2a674e21 AppKit`-[NSView viewWillDraw] + 1107
    frame #12: 0x00007fff2adeb6cf AppKit`_NSViewWillDraw + 45
    frame #13: 0x00007fff2a674e21 AppKit`-[NSView viewWillDraw] + 1107
    frame #14: 0x00007fff2adeb6cf AppKit`_NSViewWillDraw + 45
    frame #15: 0x00007fff2a6746b9 AppKit`-[NSView _sendViewWillDrawInRect:clipRootView:] + 1640
    frame #16: 0x00007fff2a672efd AppKit`-[NSView displayIfNeeded] + 1142
    frame #17: 0x00007fff2a672a52 AppKit`-[NSWindow displayIfNeeded] + 321
    frame #18: 0x00007fff2ae1360d AppKit`___NSWindowGetDisplayCycleObserver_block_invoke.5902 + 308
    frame #19: 0x00007fff2a67255e AppKit`__37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 695
    frame #20: 0x00007fff38314877 QuartzCore`CA::Transaction::run_commit_handlers(CATransactionPhase) + 49
    frame #21: 0x00007fff38313339 QuartzCore`CA::Transaction::commit() + 171
    frame #22: 0x00007fff2ae2aa72 AppKit`__65+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayRefresh]_block_invoke + 283
    frame #23: 0x00007fff2cfb8257 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    frame #24: 0x00007fff2cfb817f CoreFoundation`__CFRunLoopDoObservers + 527
    frame #25: 0x00007fff2cf9a6f8 CoreFoundation`__CFRunLoopRun + 1240
    frame #26: 0x00007fff2cf99f93 CoreFoundation`CFRunLoopRunSpecific + 483
    frame #27: 0x00007fff2c284d96 HIToolbox`RunCurrentEventLoopInMode + 286
    frame #28: 0x00007fff2c284a0f HIToolbox`ReceiveNextEventCommon + 366
    frame #29: 0x00007fff2c284884 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 64
    frame #30: 0x00007fff2a533a3b AppKit`_DPSNextEvent + 2085
    frame #31: 0x00007fff2acc9e34 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3044
    frame #32: 0x000000010017843a libSDL2-2.0.0.dylib`Cocoa_PumpEvents(_this=<unavailable>) at SDL_cocoaevents.m:438 [opt]
    frame #33: 0x00000001000d5ecd libSDL2-2.0.0.dylib`SDL_WaitEventTimeout_REAL [inlined] SDL_PumpEvents_REAL at SDL_events.c:645 [opt]
    frame #34: 0x00000001000d5eba libSDL2-2.0.0.dylib`SDL_WaitEventTimeout_REAL(event=0x00007ffeefbff1c8, timeout=-1) at SDL_events.c:680 [opt]
    frame #35: 0x00000001000030e1 wolf3d`display + 49
    frame #36: 0x00000001000012b9 wolf3d`main + 265
    frame #37: 0x00007fff54ed8015 libdyld.dylib`start + 1
/Users/vgauther/Desktop/check_compil/SDL2-2.0.9/src/video/cocoa/SDL_cocoamodes.m:118:11: warning: 'CGDisplayModeCopyPixelEncoding' is deprecated: first deprecated in macOS 10.11 [-Wdeprecated-declarations]
    fmt = CGDisplayModeCopyPixelEncoding(vidmode);
          ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:176:34: note: 'CGDisplayModeCopyPixelEncoding' has been explicitly marked deprecated here
CG_EXTERN CFStringRef __nullable CGDisplayModeCopyPixelEncoding(
                                 ^
/Users/vgauther/Desktop/check_compil/SDL2-2.0.9/src/video/cocoa/SDL_cocoamodes.m:172:64: warning: 'CGDisplayIOServicePort' is deprecated: first deprecated in macOS 10.9 [-Wdeprecated-declarations]
    CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
                                                               ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDisplayConfiguration.h:372:24: note: 'CGDisplayIOServicePort' has been explicitly marked deprecated here
CG_EXTERN io_service_t CGDisplayIOServicePort(CGDirectDisplayID display)
                       ^
2 warnings generated.
  CC     build/SDL_cocoamouse.lo
  CC     build/SDL_cocoamousetap.lo
  CC     build/SDL_cocoaopengl.lo
/Users/vgauther/Desktop/check_compil/SDL2-2.0.9/src/video/cocoa/SDL_cocoaopengl.m:219:21: warning: 'NSOpenGLPFAStereo' is deprecated: first deprecated in macOS 10.12 [-Wdeprecated-declarations]
        attr[i++] = NSOpenGLPFAStereo;
                    ^
/System/Library/Frameworks/AppKit.framework/Headers/NSOpenGL.h:78:2: note: 'NSOpenGLPFAStereo' has been explicitly marked deprecated here
        NSOpenGLPFAStereo NS_ENUM_DEPRECATED_MAC(10_0, 10_12)        =   6,
        ^
1 warning generated.
  CC     build/SDL_cocoaopengles.lo
  CC     build/SDL_cocoashape.lo
  CC     build/SDL_cocoavideo.lo
  CC     build/SDL_cocoavulkan.lo
  CC     build/SDL_cocoawindow.lo
/Users/vgauther/Desktop/check_compil/SDL2-2.0.9/src/video/cocoa/SDL_cocoawindow.m:342:11: warning: 'setAcceptsTouchEvents:' is deprecated: first deprecated in macOS 10.12.2 - Use allowedTouchTypes instead [-Wdeprecated-declarations]
    [view setAcceptsTouchEvents:YES];
          ^
/System/Library/Frameworks/AppKit.framework/Headers/NSView.h:274:16: note: property 'acceptsTouchEvents' is declared deprecated here
@property BOOL acceptsTouchEvents NS_DEPRECATED_MAC(10_6, 10_12_2, "Use allowedTouchTypes instead");
               ^
/System/Library/Frameworks/AppKit.framework/Headers/NSView.h:274:16: note: 'setAcceptsTouchEvents:' has been explicitly marked deprecated here
1 warning generated.

最佳答案

main中,您没有检查ft_sdl_init的结果是否正确,因此,即使使用无效的窗口/渲染器,您的程序也可能运行。

这个条件绝对没有任何作用:

        if (!var->sdl.window || !var->sdl.render)
            return ;

如果为真,则离开该函数。如果为 false,它也会离开该函数。没有区别。

最重要的是,如果窗口/渲染器创建失败,SDL 将返回 NULL。来自 SDL wiki on SDL_CreateWindow :

Returns the window that was created or NULL on failure; call SDL_GetError() for more information.

关于c - 为什么函数 SDL_WaitEvent (SDL2) 在我的代码中出现错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59079441/

相关文章:

javascript - 如何禁用 textarea 上的 ENTER 键?

android - 按钮单击事件未在取景器的第二个 View 中触发

c++ - 如何使用代码块编译 64 位 SDL 代码(没有管理员权限)

c++ - 让 Sprite 沿着一个角度行走

JavaFX 2 将 ImageView 拖动到按钮

c++ - SDL:制作静态文本变量

c - recvfrom() 错误 10035 使用非阻塞套接字

计数参数不一致,MPI_Bsend/MPI_Recieve

c++ - 调用 c 函数时出现段错误

c++ - 乘法溢出测试