SDL 2.0.5 and stb_image

I recently tried to load a PNG file into an SDL_Texture to render on screen. SDL supports BMP only by default, so I’d need to grab a library. SDL_Image exists as an extension to SDL and runs on any platform supported by SDL. It’s a great option that I’ll probably use it at some point, but I’ve always been a fan of the lightweight stb libraries. So for fun I decided to go with stb_image.

stb_image

As you may have guessed, this is useful for loading images of all types. From the header itself:

  Primarily of interest to game developers and other people who can
  avoid problematic images and only need the trivial interface

    JPEG baseline & progressive (12 bpc/arithmetic not supported, 
same as stock IJG lib)
    PNG 1/2/4/8/16-bit-per-channel
    TGA (not sure what subset, if a subset)
    BMP non-1bpp, non-RLE
    PSD (composited view only, no extra channels, 8/16 bit-per-channel)
    GIF (*comp always reports as 4-channel)
    HDR (radiance rgbE format)
    PIC (Softimage PIC)
    PNM (PPM and PGM binary only)

The documentation is quite verbose and complete, and it makes what we want to do very easy. Just add stb_image.h to your includes (or drop it straight into your project) and add this to your include block:

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

SDL has a nice sample that loads a PNG using stbi_load and creates a surface from it. However! Disaster strikes when you try to compile the code!

The Link Error

2>Main.obj : error LNK2019: unresolved external symbol SDL_CreateRGBSurfaceWithFormatFrom referenced in function SDL_main

Since everything seemed alright on my end I immediately went to the SDL bug database, and yup, lo and behold I wasn’t alone in this. It looks like the DLL files were updated but libs were not rebuild for SDL 2.0.5. Not to worry, I learnt something new! How to rebuild .lib files using only a DLL. It’s very simple, I followed the steps outlined here, but I’ll re-list them for completions sake.

  1. Open the developer command prompt located in:
    Start->Programs->Microsoft Visual Studio->Tools
  2. Run the dumpbin command to list all of the functions exported by the DLL
    dumpbin /exports C:\path\to\SDL2.dll
    

    This prints a whole bunch of stuff to the console that looks like this

        ordinal hint RVA      name
    
              1    0 00038180 SDL_AddEventWatch
              2    1 000385C0 SDL_AddHintCallback
              3    2 000398E0 SDL_AddTimer
              4    3 00038B70 SDL_AllocFormat
              5    4 00038B90 SDL_AllocPalette
              6    5 00039090 SDL_AllocRW
              7    6 00037DB0 SDL_AtomicAdd
              8    7 00037D80 SDL_AtomicCAS
              ...
    
  3. What we wanna do now is copy paste all of the function names (and only the function names) into a new SDL2.def file and add the line “EXPORTS” up the top. It will look like this:

    EXPORTS
    SDL_AddEventWatch
    SDL_AddHintCallback
    SDL_AddTimer
    SDL_AllocFormat
    SDL_AllocPalette
    SDL_AllocRW
    SDL_AtomicAdd
    SDL_AtomicCAS
    ...
    
  4. Hurray! We can finally create the .lib from this .def file
    lib /def:C:\path\to\SDL2.def /OUT:C:\path\to\SDL2.lib
    

The good news is that an SDL 2.0.6 release is underway and this should be fixed simply by recompiling the libraries

2 thoughts on “SDL 2.0.5 and stb_image”

  1. Thanks for this post. I encountered this exact problem and recreating the LIB fixed it.

    But there’s one small, critical typo in the last command. As written, it will overwrite your DLL!

    Instead, it should be “lib /def:C:\path\to\SDL2.def /out:C:\path\to\SDL2.lib”

Leave a Reply