You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Allegro 5在VS2022中注册键盘事件源时出现访问违规求助

Allegro 5键盘模块访问违规错误(0xC0000005)的解决方法

问题原因分析

你遇到的0xC0000005访问违规错误,核心原因有两个:

  1. 键盘未初始化就尝试获取事件源:代码开头调用了al_uninstall_keyboard(),但后续未调用al_install_keyboard()重新初始化键盘,导致al_get_keyboard_event_source()返回空指针,注册事件源时访问了空指针指向的无效内存地址。
  2. 初始化顺序错误:Allegro 5在Windows等平台上,必须先创建显示窗口(al_create_display),才能正确初始化输入设备(比如键盘),否则输入设备的上下文无法建立。

具体解决步骤

  • 移除不必要的al_uninstall_keyboard()调用,或在使用键盘前显式调用al_install_keyboard()完成初始化。
  • 调整代码执行顺序:先创建显示窗口,再初始化键盘、创建事件队列并注册事件源。
  • 确保事件循环在所有必要资源(显示、字体、事件队列)初始化完成后再启动。

修正后的完整代码

#include <allegro5/allegro5.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>

struct painel
{
    int     atmid;
    char    contid;
    int     Minatm;
    int     Minacont;
};

struct painel tmt[40];

int i = 0;

int main()
{
    // 初始化Allegro核心库和附加组件
    al_init();
    al_init_font_addon();
    al_init_ttf_addon();

    // 启动动画提示
    printf(" __________________________");
    printf("\n|                          |\n| system on                |\n|power suply  is ok        |\n|__________________________|\n");
    Sleep(100);
    do {
        printf("\t starting \\ \r ");
        Sleep(90);
        printf("\t starting | \r ");
        Sleep(90);
        printf("\t starting / \r ");
        Sleep(90);
        printf("\t starting | \r ");
        Sleep(90);
        printf("\t starting \\ \r ");
        i++;

    } while (i <= 10);
    system("cls");
    
    // 第一步:创建显示窗口(必须在输入设备初始化前)
    ALLEGRO_DISPLAY* display = al_create_display(1080,640);
    if (!display) return 1;
    al_set_window_title(display, "ATM");

    // 第二步:初始化键盘
    if (!al_install_keyboard()) {
        fprintf(stderr, "无法初始化键盘\n");
        return 2;
    }

    // 第三步:创建事件队列并注册事件源
    ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue();
    if (!event_queue) {
        fprintf(stderr, "无法创建事件队列\n");
        return 3;
    }
    al_register_event_source(event_queue, al_get_keyboard_event_source());
    // 注册显示事件,处理窗口关闭操作
    al_register_event_source(event_queue, al_get_display_event_source(display));

    // 加载字体
    ALLEGRO_FONT* font = al_load_ttf_font("COMICATE.ttf", 64, 0);
    if (!font) {
        fprintf(stderr, "无法加载字体\n");
        return -2;
    }

    // 绘制初始界面
    al_clear_to_color(al_map_rgb(180, 255, 240));
    al_draw_text(font, al_map_rgb(240, 0, 0), 20, 20, 0, "oi");
    al_flip_display();

    // 事件循环
    bool done = false;
    while (!done)
    {
        ALLEGRO_EVENT events;
        al_wait_for_event(event_queue, &events);

        if (events.type == ALLEGRO_EVENT_KEY_DOWN)
        {
            switch (events.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                    done = true;
                    break;
            }
        }
        // 处理窗口关闭事件
        else if (events.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
            done = true;
        }
    }

    // 清理资源
    al_destroy_font(font);
    al_destroy_event_queue(event_queue);
    al_destroy_display(display);
    return 0;
}

关键修改说明

  1. 移除了al_uninstall_keyboard(),新增al_install_keyboard()显式调用,确保键盘设备正确初始化。
  2. 调整初始化顺序:先创建显示窗口,再初始化键盘、事件队列,符合Allegro 5的平台要求。
  3. 新增显示事件注册,处理窗口关闭操作,提升程序健壮性。
  4. 将界面绘制代码移到事件循环之前,确保初始界面正常显示。
  5. 新增事件队列销毁操作,避免内存泄漏。

内容的提问来源于stack exchange,提问作者wendel212 Lego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 04:10:28