Allegro 5在VS2022中注册键盘事件源时出现访问违规求助
Allegro 5键盘模块访问违规错误(0xC0000005)的解决方法
问题原因分析
你遇到的0xC0000005访问违规错误,核心原因有两个:
- 键盘未初始化就尝试获取事件源:代码开头调用了
al_uninstall_keyboard(),但后续未调用al_install_keyboard()重新初始化键盘,导致al_get_keyboard_event_source()返回空指针,注册事件源时访问了空指针指向的无效内存地址。 - 初始化顺序错误: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; }
关键修改说明
- 移除了
al_uninstall_keyboard(),新增al_install_keyboard()显式调用,确保键盘设备正确初始化。 - 调整初始化顺序:先创建显示窗口,再初始化键盘、事件队列,符合Allegro 5的平台要求。
- 新增显示事件注册,处理窗口关闭操作,提升程序健壮性。
- 将界面绘制代码移到事件循环之前,确保初始界面正常显示。
- 新增事件队列销毁操作,避免内存泄漏。
内容的提问来源于stack exchange,提问作者wendel212 Lego
相关产品推荐
相关产品推荐

