【问题标题】:Access violation at 0x00000000 Loading PNG File With SDL_image Library0x00000000 处的访问冲突使用 SDL_image 库加载 PNG 文件
【发布时间】:2015-11-11 18:42:52
【问题描述】:

我在 Visual C++ 2010 Express 中使用 SDL2 2.0.3 库和 SDL_image 库 2.0.0。我正在利用 SDL_image 库从资源文件夹中加载各种 PNG 和 JPEG 文件。虽然库初始化没有任何错误并加载 BMP 和 JPEG 文件,但在给定 PNG 文件时它会中断。

“appname.exe 中 0x00000000 处未处理的异常:0xC0000005:访问冲突。”

在我的纹理管理器(为程序存储和管理纹理的对象)内部,是一个从给定文件名字符串加载纹理的函数。这是代码,包括我在实现 SDL_image 进行加载之前使用的注释行。上面的异常是在bitmapSurface = IMG_Load(... 行内抛出的。

/**
 * Attempts to load a given image file and reports to the console any failures
 * 
 * @param fileName The exact file name of the resource to be loaded
 * @return The SDL_Texture loaded from the given fileName
 */
SDL_Texture* TextureManager::loadTexture(string fileName)
{
    //Create our surface in RAM
    SDL_Surface *bitmapSurface = NULL;
    //bitmapSurface = SDL_LoadBMP(fileName.c_str()); //OLD METHOD; standard SDL, BMP only
    bitmapSurface = IMG_Load(fileName.c_str());      //NEW METHOD; SDL_image lib, many formats

    //Verify it exists
    if (bitmapSurface == NULL)
        cout << "Image resource not loaded: " << fileName << " Message: " << IMG_GetError() << endl;

    //Create a texture in VRAM from the surface
    SDL_Texture *bitmapTexture = NULL;
    bitmapTexture = SDL_CreateTextureFromSurface(this->renderer, bitmapSurface);

    //Verify it exists
    if (bitmapTexture == NULL)
        cout << "Failed to create texture: " << fileName << endl;

    return bitmapTexture;
}

调用栈:

    00000000()  
    SDL2_image.dll!6a887a01()   
    [Frames below may be incorrect and/or missing, no symbols loaded for SDL2_image.dll]    
    SDL2.dll!6c77da4b()     
    SDL2_image.dll!6a88792e()   
    SDL2_image.dll!6a881693()   
    SDL2_image.dll!6a8817e9()   
> appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName)  Line 143 + 0xe bytes  C++
    00daf5e0()  

这是我的 TextureManager 的构造函数:

/**
 * Creates a new TextureManager with the current SDL_Renderer
 * 
 * @param renderer The current renderer instance of the current graphic window
 */ 
TextureManager::TextureManager(SDL_Renderer* renderer)
{
    //Assign our renderer link
    this->renderer = renderer;

    //Create the vector to hold textures
    this->textures = new vector<Texture*>();

    //SDL_image initialization
    int flags   = IMG_INIT_JPG|IMG_INIT_PNG;
    int initted = IMG_Init(flags); //Use IMG_Quit(); at closing

    if(initted&flags != flags)
    {
        //Handle error
        printf("IMG_Init: Failed to init required jpg and png support!\n");
        printf("IMG_Init: %s\n", IMG_GetError());
    }
    else
    {
        cout << "SDL_Image initialized for JPEG and PNG support" << endl;
    }
}

供您参考,我使用的是最新的 Windows 10 x64。双 NVidia GTX 550ti 的图形驱动程序也是最新的。 所有 DLL 文件(包括 pnglib dll)都在调试文件夹中并进行加载。如果我从程序中删除 DLL 文件,则图像无法加载并提供上面为 NULL 表面编码的消息。没有异常发生。

问题总结: 为什么会抛出这个异常,为什么它只针对 PNG 文件抛出,以及当调用堆栈的详细信息在我的调用结束时,我该如何跟踪它似乎工作正常?我做错了什么,还是我可能错过了配置步骤?

编辑:感谢@Nandu,我重新编译了 DLL SDL_image,并在此处获得了更好的调用堆栈输出:

    00000000()  
> SDL2_image.dll!IMG_LoadPNG_RW(SDL_RWops * src)  Line 375 + 0x11 bytes C
    SDL2_image.dll!IMG_LoadTyped_RW(SDL_RWops * src, int freesrc, const char * type)  Line 193 + 0x12 bytes C
    SDL2_image.dll!IMG_Load(const char * file)  Line 134 + 0xf bytes    C
    appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName)  Line 143 + 0xe bytes    C++
    appname.exe!TextureManager::loadFromDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > relPath)  Line 117 + 0x73 bytes  C++
    appname.exe!SDL_main(int argc, char * * argv)  Line 31  C++
    appname.exe!main(int argc, char * * argv)  Line 140 + 0xd bytes C
    appname.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes  C
    appname.exe!mainCRTStartup()  Line 371  C
    kernel32.dll!77963744()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!77c3a064()    
    ntdll.dll!77c3a02f() 

这表明问题出现在 IMG_png.c 的第 374 行:

 /* Create the PNG loading context structure */
    png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING,
                      NULL,NULL,NULL);

VS报告lib此时为NULL,这可以解释错误!问题变成了,为什么它是NULL?似乎这段代码应该对此进行检查,但尽管如此,在万能的互联网上似乎没有其他人遇到这个问题。

【问题讨论】:

  • 您有代码来检查 NULL 返回值,但您的代码继续执行,好像没有任何问题。 //Verify it exists if (bitmapSurface == NULL)
  • 你拥有 DLL 文件吗?如果是,请在关闭优化的情况下重建它(同时关闭应用程序的优化)。使用 dll 中内置的符号,您可以收集调用堆栈和此崩溃的起源。
  • @PaulMcKenzie 是的,我的代码进一步抵抗 NULL 纹理,我只想要警告。
  • @Nandu 我以前从未这样做过,但我会试一试。如果您有任何建议或教程,我们将不胜感激。
  • 我会说你的 libpng 库没有正确加载,在这种情况下我会尝试从源代码构建整个东西并调试它。

标签: c++ visual-studio-2010 sdl-2 sdl-image


【解决方案1】:

非常感谢大家的帮助,但是像往常一样,问题很明显! 正如@Gigi 所说:SDL_Image IMG_Load fails on png with: "Failed loading libpng16-16.dll:"

我建议您尝试包含所有其他内容 - 可能存在您和我都没有意识到的依赖关系。其实我刚刚查了一下,libpng需要zlib:libpng.org/pub/png/libpng.html

我不确定为什么我最初的搜索或建议没有显示该帖子。

我最初排除了我没有使用(或在我的代码中初始化)的其他文件格式的 DLL,但是一旦我包含了 zlib DLL,bingo。 PNG 完全按预期加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2013-10-11
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多