Reputation: 1237
Okay... so I am using Visual Studio 2010 making a win32 game... thingy. I am using a third party library that handles the graphics. It reads in a png file, creates the window, displays everything, and generally does a bunch of convenient low-level things that no one wants to deal with themselves.
Well, like any aspiring OCD programmer, I am trying to embed the png inside the executable because I don't like it to just be hangin' out in the directory for everyone to see. So, I got the source code, and started modifying it to, instead of load the png from a file, load it from a resource. I added the following code:
HRSRC hRsrc = FindResourceW(NULL, recName, recType);
if (GetLastError() != 0)
{
char b[100];
leave("Couldn't find resource", itoa(GetLastError(), b, 10));
}
HGLOBAL hGlob1 = LoadResource(NULL, hRsrc);
int size = SizeofResource(NULL, hRsrc);
HGLOBAL hGlobal = GlobalAlloc(GMEM_FIXED, size);
LPVOID resPtr = LockResource(hGlob1);
LPSTREAM pStream;
memcpy(hGlobal, resPtr, size);
FreeResource(hGlob1);
CreateStreamOnHGlobal(hGlobal, true, &pStream);
buffer.resize((size_t)size);
pStream->Read(&buffer[0], size, NULL);
return;
recName
is the resource's name. recType
is the resource's type (these are both passed in as parameters). leave
is a custom function that displays a popup message. buffer
is the vector into which the png contents are read.
This library is compiled out into a statically linked library that my own code uses. So, my code does the actual embedding of the resources. Now, the thing is, this works, but only on a select few computers. I am able to run it, as is precisely one of my friends. On anyone else's computer, GetLastError()
returns a 127, and as a result, the program craps out. According to msdn, error 127 is The specified procedure could not be found.
...whatever that means.
I have other embedded files in my executable, including mp3s and dlls, all made the same way, and they work fine (and, again, this png even works fine on my own computer), so I know it's not an issue of embedding things; I think I've pretty much got that down.
So then... what is error code 127 trying to tell me? Do my users' computers not know how to run function FindResourceW? If so, that makes absolutely no sense, because my code uses that function in other places, for loading the mp3s, and that works as well (and in fact, has worked, before I started trying to embed the png). Basically, I have never seen this kind of problem before, and I am stumped. :|
Upvotes: 0
Views: 881
Reputation: 125727
You are not correctly using GetLastError
or FindResourceW
.
The documentation for FindResourceW
(linked above) clearly says that FindResourceW
returns a module handle (HRSR
), and that you should check GetLastError
if it returns NULL (emphasis added).
Return value
Type: HRSRC
If the function succeeds, the return value is a handle to the specified resource's information block. To obtain a handle to the resource, pass this handle to the LoadResource function.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
From the documentation on GetLastError
(again, linked above, and again emphasis mine:
Return value
The return value is the calling thread's last-error code.
The Return Value section of the documentation for each function that sets the last-error code notes the conditions under which the function sets the last-error code. Most functions that set the thread's last-error code set it when they fail. However, some functions also set the last-error code when they succeed. If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not.
This says that unless the function is documented to set the last error code when it succeeds, the error code should only be used to indicate status if the function fails. Your code makes the assumption that if GetLastError
is other than 0 then FindResourceW
failed, and that assumption is wrong. :-) Because of that failed assumption, your code (wrongly) enters the if
block and calls leave
when it shouldn't, which would logically mean that the code after the if
block ends is never executed.
FindResourceW
is clearly documented to only SetLastError
if it fails and returns NULL
. The error value you're assuming is from FindResourceW
is from somewhere else in your code that's setting the error value (which your code is apparently not reading).
So this would be closer to correct use (not a C++ guy myself):
HRSRC hRsrc = FindResourceW(NULL, recName, recType);
if (!hRsrc)
{
char b[100];
leave("Couldn't find resource", itoa(GetLastError(), b, 10));
}
Upvotes: 1