Search code examples
c#dllpinvokesdl

Can't find SDL_LoadBMP() entry point in 'SDL.DLL' with PInvoke


I'm trying to marshal data between SDL and my C# .NET program. The first few calls that I make into SDL.DLL work fine, inasmuch as I get no error and my Windows console app does open an empty application window:

My_SDL_Funcs.SDL_Init(0x0000FFFF); // SDL_INIT_EVERYTHING
IntPtr scrn = My_SDL_Funcs.SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0x00000000); // SDL_SWSURFACE
screen = (SDL_Surface)Marshal.PtrToStructure(scrn, typeof(SDL_Surface));
My_SDL_Funcs.SDL_WM_SetCaption("Hello World", null);
// ...

When I try to call SDL_LoadBMP() however, I get this runtime error:

Unable to find an entry point named 'SDL_LoadBMP' in DLL 'SDL'.

The SDL doc says that SDL_LoadBMP takes a const char* file name and returns a pointer to a SDL_Surface struct.

I first tried declaring the PInvoke as:

[DllImport("SDL", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr SDL_LoadBMP([MarshalAs(UnmanagedType.LPWStr)] string file);

When this didn't work, I tried:

public static extern IntPtr SDL_LoadBMP(IntPtr file);

and used:

IntPtr fn = Marshal.StringToHGlobalAnsi(filename);
IntPtr loadedImage = My_SDL_Funcs.SDL_LoadBMP(fn);

Assuming that that the function actuall does exist in this library (SDL.DLL version 1.2.14), am I using the wrong invocation for a const char*?


Solution

  • I downloaded the DLL version you are using, and could not find an export for SDL_LoadBMP.

    There is a SDL_LoadBMP_RW, though, so you could rig up your own helper call like so:

    private const string SDL = "SDL.dll";
    
    [DllImport(SDL, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
    public static extern IntPtr SDL_LoadBMP_RW(IntPtr src, int freesrc);
    
    [DllImport(SDL, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
    public static extern IntPtr SDL_RWFromFile(string file, string mode);
    
    public static IntPtr SDL_LoadBMP(string file)
    {
        return SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1);
    }
    

    UPDATE:

    I had a look through the code, and the call you are looking for is defined as a macro, so that is why you can't call it directly. Using the above code basically does the same thing as the macro defintion:

    #define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)