SDL_image 2.0.1 tries to load "shcore.dll" in Windows 7?


#1

Hello. I am having a pretty weird bug (?) with SDL_image. When I call IMG_Init like: IMG_Init(IMG_INIT_PNG) and I check for the return value, I get an error like Failed loading SHCORE.DLL: Could not find the specified module..

Now, this is pretty odd, because shcore.dll is only available in Windows 8.1 and above, and I researched a bit and it seems to be called by IMG_LoadPCX_RW – but I don’t even use that?! (I’m sure it’s an error on my part).

If the provided libpng16-16.dll is not present anywhere in the system, IMG_Init returns as if everything was init’d properly. This is also quite weird. Shouldn’t it also error out, but say that it can’t find libpng16-16? I used ProcessMonitor to trace the program’s calls and it really cannot find libpng16-16.dll, just like shcore.dll, so yeah.

Anyways, I’ve been banging my head on this for a day now. Any help is appreciated.


#2

That error message gets set by SDL2. The windows video driver checks for the DLL and loads some functions if it is present. The initialization does not fail if it is not. The error messages are only valid if there actually was an error, otherwise they’re undefined.

Are you checking the return value of IMG_Init correctly? The documentation says you have to do something like this.

// load support for the JPG and PNG image formats
int flags=IMG_INIT_JPG|IMG_INIT_PNG;
int initted=IMG_Init(flags);
if((initted&flags) != flags) {
    printf("IMG_Init: Failed to init required jpg and png support!\n");
    printf("IMG_Init: %s\n", IMG_GetError());
    // handle error
}

I can’t think of anything else currently.


#3

Yes, I have noticed my problem now! This is what I was doing, essentially:

// tries to load shcore.dll, fails, but shcore.dll isn't essential so returns
// zero meaning success
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
    puts(SDL_GetError());
    exit(1);
}

// inits png okay, but returns nonzero for success so this enters into the if
if (IMG_Init(IMG_INIT_PNG) != 0) {
    puts(SDL_GetError()); // SDL_GetError contains the error from SDL_Init,
                          // which is "... could not find shcore.dll ..."
    exit(1); // the program exits
}

I misread the documentation and thought IMG_Init was the same as SDL_Init, causing that unfortunate bug. I see how it is done now, thank you! :smiley:


#4

[ChliHug] ChliHug https://discourse.libsdl.org/u/chlihug
July 12

That error message gets set by SDL2. The windows video driver checks for
the DLL and loads some functions if it is present. The initialization
does not fail if it is not. The error messages are only valid if there
actually was an error, otherwise they’re undefined.

Would be nicer if SDL_Error() ('s internal string) was cleared
afterwards, to avoid such confusion.

(Am I guessing right that this is for HighDPI? ;))

Cheers,
Daniel


#5

Well. It’s not going to have any priority, but I put a bug report into bugzilla.

It’s for getting the DPI values. SDL doesn’t set DPI awareness on Windows yet. I think someone already proposed a patch, though. It’s such a shame Microsoft made this so weird.


#6

I’m not against this, but for compatibility reasons it would have to be controlled by a hint rather than being the default behavior.


#7

Are there any SDL applications that do not surprisingly break if DPI
scaling is used on Windows 8.1+?
(Except for ones that already set DPI awareness themselves)

Has anyone investigated this further, so far the only ones I know about
use OpenGL for rendering, that might or might not be related (I don’t
closely follow any SDL applications not using an OpenGL renderer).
Are SDL applications using SDL’s software rendering or SDL_Render.h
(with Direct3D) also affected?

If so, I think SDL should set it by default, a hint could be used to
disable it. Otherwise, maybe SDL should do it by default if
SDL_WINDOW_OPENGL is set?

Either way, the default should be to minimize breakage of most existing
applications.

Cheers,
Daniel