fachtnaroe.net
— because if it was easy, everyone would do it

  • Credits : John S and John C

Coding is one of the highest art forms achieved by mankind; an idea - just an electrical impulse - is made real in an alternate electronic universe; the created idea however, does not have physical form, and yet can change the physical world; it cannot be touched, and yet may touch all mankind.

Error displaying images using SDL: Can't call method "w" on an undefined value

OS: Fedora Core; Release: 17; Arch: x86_64;

Summary: you're using SDL but your program is stopping unexpectedly because it is looking for an image file which it can't find.

Problem: the image file does exist but can't be loaded because to do so SDL wants to use a shared library file which can't be found; the library file may exist but doesn't get linked to as part of any package installed; the link must therefore be provided manually.

This scenario assumes code like this (taken from sample file lander.pl):

my $background = SDL::Image::load('images/background.jpg');
my $background_rect = SDL::Rect->new(0,0,
    $background->w,  # <- program is stopping here
    $background->h,
); 

If you get the error:

Can't call method "w" on an undefined value...
this means that the image cannot be found where your program expects it, or there's a library error.

Firstly, confirm that you're correctly referencing the image file. That means test! Just because you feel you are correctly referencing, doesn't mean that you are correctly referencing; the simplest test is to either use the full path to the image file, or try to use a different file.

If the problem persists, you may have a shared libraries problem.

Before you assume that, however, go back and test whether all the SDL packages have been installed. The command:

yum install *SDL*  cpan
is a good start. Follow it with:
cpan SDLx::App
... from which command you will accept all the default values. Do not try to proceed forward until all issues are resolved. Now test your program again. If the original error still persists, continue as below.

To enable more detailed debugging, between the two ($background/$background_rect) lines above, use:

if (!(-e $image_file_name)) {
  print "File doesn't exist.\n";
}
to confirm file existance. If the file is not flagged as missing but you're getting the same error, we can assume we have a library problem and move to the next stage.

This code, inserted after the SDL::Image::load and before the call to SDL::Rect which is stopping the program, will give more information:

if (!$background) {
  my $error = SDL::get_error;
  print "Error loading image: $error\n";
  exit;
} 

The more detailed information which I then received was:

Error loading image: Failed loading libjpeg.so.8: libjpeg.so.8: cannot open shared object file: No such file or directory
which led to using:
yum provides */libjpeg.so.8
which should tell me the package which provided the file (sometimes it doesn't so skip to locate below). After using:
yum reinstall package_name
the problem persisted. Therefore I used:
locate libjpeg.so.8
which told me the file existed in the Alien-SDL directory elsewhere in the system. The solution was to provide a link (known in MS Windows as a shortcut) to the file. Use the output of the locate command from above to customise this:
ln -s  /usr/local/share/perl5/auto/share/dist/Alien-SDL/put your Alien-SDL version here/lib/libjpeg.so.8  /lib64/libjpeg.so.8 
which solved the problem. You may have to use different file and directory names, but this may resolve the issue for you too.
Last updated: 20150326-09:43