Dub / Derelict confusion

Mike Parker via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Nov 20 17:22:36 PST 2014


On 11/21/2014 5:57 AM, Paul wrote:

>
> This is a tad off topic now but I'm struggling to get a window on screen
> as SDL_CreateWindow is failing, here's what I've got:
>
> try{
>      DerelictSDL2.load();
> }catch(Exception e){
>      writeln("Failed to load DerelictSDL2 :( %s", e.msg);
>      return;
> }

Before getting to your issue, I'd like to point out that this is a 
needless redundancy. You are adding anything by catching an exception 
here and printing to the console that the library didn't load. The 
exception message will tell you that already. I suggest you just remove 
the try..catch and let the exception propagate. The only reason to catch 
a DerelictException here is if you want to do something other than print 
the message to the console, like display a message box or write to a log 
file.


>
> try{
>      SDL_Init(SDL_INIT_EVERYTHING);
> }catch(Exception e){
>       writeln("Can't init SDL :( %s", e.msg);
>       return;
> }
>

SDL_Init isn't goint to throw an exception. It can't. It's a function in 
a C library and C doesn't know anything about D exceptions. If you look 
at the documentation for SDL_Init[1], you will find that it returns a 
negative number on failure and 0 on success.

if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
  // See below for how to handle this
}

>
> SDL_Window *testWindow;
> //temporary magic numbers ahoy
> testWindow = SDL_CreateWindow( "Test Window", SDL_WINDOWPOS_UNDEFINED,
> SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_RESIZABLE );
> if( testWindow == null ) {
>      writeln("Window could not be created!");
>      return;
> }     else {
>      SDL_Surface* testSurface;
>      testSurface = SDL_GetWindowSurface(testWindow);
> }
>
> Everything seems to initialise ok but SDL_CreateWindow always returns
> null. For some reason I can't use DerelictException which I guess might
> help me dig deeper. AFAIK there are no issues with this machine's
> hardware - I can certainly run other SDL-based apps on it.
>

Again, DerelictExceptions aren't going to help you here. They are only 
thrown when the load function fails (to manipulate a DerelictException 
directly, import derelict.util.exception.) To get an error message out 
of SDL, you need to call SDL_GetError, which returns a const( char )*.

void printSDLError( string msg ) {
   import std.conv : to;
   import std.stdio : writefln;

   writefln("%s: %s", msg, to!string( SDL_GetError() ));
}

...
if( testWindow == null )
{
   printSDLError( "Failed to create window." );
   return;
}

I prefer to wrap it up in a subclass of Error. Others may prefer 
Exception, but when I throw an SDLError I don't intend to catch it. I 
really want the app to exit.

class SDLError : Error
{
     public static string errStr() @property
     {
         import std.conv : to;
         import derelict.sdl2.sdl : SDL_GetError;
         return to!string( SDL_GetError() );
     }

     public this( string msg, string file = __FILE__, size_t line = 
__LINE__ )
     {
         import std.string : format;

         auto fmsg = format( "%s: %s", msg, errStr );
         super( fmsg, file, line );
     }
}

Now it becomes:

DerelictSDL2.load();

if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
{
   throw new SDLError( "Failed to initialize SDL" );
}

testWindow = SDL_CreateWindow( ... );
if( !testWindow )
{
   throw new SDLError( "Failed to create window" );
}

Whichever approach you choose, SDL_GetError will shed light on why any 
SDL call failed as long as you call it immediately upon failure.

[1] 
https://wiki.libsdl.org/SDL_Init?highlight=%28%5CbCategoryInit%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29


More information about the Digitalmars-d-learn mailing list