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

使用D语言+SDL2/SDL2_image开发时遇-1073741819访问违例错误

D语言SDL2+SDL2_image访问违例(-1073741819)问题排查与修复

核心问题分析

  • 未加载DerelictSDL2_image动态库:仅调用DerelictSDL2.load()不足以绑定SDL_image的函数,直接调用IMG_Init会因函数指针无效触发访问违例。
  • SDL_image初始化判断逻辑错误:原代码的条件判断完全不符合预期,无法正确检测初始化失败。

修正后的完整代码

import std.stdio;
import derelict.sdl2.sdl;
import derelict.sdl2.image;

void main() {
    // 加载SDL2和SDL2_image动态库
    DerelictSDL2.load();
    DerelictSDL2Image.load();

    // 初始化SDL_image以支持JPG格式
    if ((IMG_Init(IMG_INIT_JPG) & IMG_INIT_JPG) == 0) {
        writeln("Failed to initialize SDL_image: ", SDL_GetError());
        return;
    }

    // 初始化SDL视频子系统
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        writeln("Failed to initialize SDL: ", SDL_GetError());
        IMG_Quit();
        return;
    }

    // 创建窗口
    SDL_Window* window = SDL_CreateWindow("Hello SDL2",
                                          SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                          500, 500, SDL_WINDOW_SHOWN);
    if (!window) {
        writeln("Failed to create window: ", SDL_GetError());
        SDL_Quit();
        IMG_Quit();
        return;
    }

    // 创建硬件加速且垂直同步的渲染器
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (!renderer) {
        writeln("Failed to create renderer: ", SDL_GetError());
        SDL_DestroyWindow(window);
        SDL_Quit();
        IMG_Quit();
        return;
    }

    // 加载图片并创建纹理
    SDL_Surface* image = IMG_Load("fdcae74b5ad91e309aa03020c7ea4f26.jpg");
    if (!image) {
        writeln("Failed to load image: ", SDL_GetError());
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        IMG_Quit();
        return;
    }
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, image);
    if (!texture) {
        writeln("Failed to create texture: ", SDL_GetError());
        SDL_FreeSurface(image);
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        IMG_Quit();
        return;
    }

    // 事件处理与渲染循环
    SDL_Event event;
    bool running = true;
    while (running) {
        // 处理事件
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT) {
                running = false;
            }
        }

        // 渲染流程:清屏 -> 复制纹理到渲染器 -> 刷新屏幕
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, null, null);
        SDL_RenderPresent(renderer);
    }

    // 资源清理(注意顺序:先创建的后销毁)
    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    IMG_Quit();
}

关键修正点说明

  1. 添加SDL2_image动态库加载:必须调用DerelictSDL2Image.load()来绑定SDL_image的所有函数,这是触发访问违例的最核心原因。
  2. 修复初始化判断逻辑:IMG_Init返回已成功初始化的标志位集合,需要用&位运算判断是否包含IMG_INIT_JPG,而不是原代码中的错误逻辑。
  3. 补充SDL_image的清理步骤:程序退出前调用IMG_Quit(),与IMG_Init配对,避免资源泄漏。
  4. 完善错误处理的清理流程:在每个错误分支中都添加IMG_Quit(),确保资源正确释放。
  5. 添加渲染逻辑:原事件循环仅处理退出事件,没有任何渲染操作,补充清屏、纹理复制和屏幕刷新的代码,让窗口正常显示内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:05:18