resources in static libraries

B

Bonj

can you embed a resource into a static libary?
I'm using a custom binary resource specified as a .bin file in the .rc file
of the static library project I've got. I use FindResource, LoadResource,
LockResource to get the resource. However FindResource is returning null. If
I use exactly the same code to retrieve a resource out of the resource of
the console application used to test the static library, then it works
perfectly. I can't see how the resource isn't being compiled into the static
library, as its size would seem to indicate that it has. It's using
GetModuleHandle(NULL) in order to get the process handle.
Any idea what could be wrong?
This is the code in the static library:

BOOL loaddata()
{
HMODULE hModule = GetModuleHandle(NULL);
HRSRC hRsrc = FindResource(hModule, MAKEINTRESOURCE(IDR_NODES), "NODES");
if(hRsrc != NULL)
{
HGLOBAL hGMem = LoadResource(hModule, hRsrc);
if(hGMem != NULL)
{
ressize = SizeofResource(hModule, hRsrc);
resdata = (NODE*)LockResource(hGMem);
if(ressize > 0) return TRUE;
else FreeResource(hGMem);
}
}
return FALSE;
}

in which hRsrc goes to NULL.
The code that works fine in the console application used to test it goes
like this:
HMODULE hModule = GetModuleHandle(NULL);
HRSRC hRsrc = FindResource(hModule, MAKEINTRESOURCE(IDR_BIN11), "BIN1");
HGLOBAL hGMem = LoadResource(hModule, hRsrc);
LPBYTE lpData = (LPBYTE)LockResource(hGMem);
DWORD dwSize = SizeofResource(hModule, hRsrc);
FreeResource(hGMem);

and it works fine.
 
C

Carl Daniel [VC++ MVP]

Bonj said:
can you embed a resource into a static libary?

No, you can't. Not as a resource anyway. Sometimes people will use a
"bin2obj" program to convert a binary blob of data into a section of
initialized const data that can be referenced by name. Such a blob can be
put into a static library, but resources can't be.

Unfortunately, MS doesn't include a 'bin2obj' program with VC++. Borland
used to ship one, but it made OMF files not COFF files, so the VC linker
would choke on them anyway. You might find such a program with a little
spelunking around the 'net.

-cd
 
B

Bonj

OK thanks
I've found you can actually get it to work but it's messy!
I basically did it by adding a blank resource file to the main application,
and then adding the relative path to the static library's resource file to
the 'resource includes' compile-time directive section of the main app's
resource file, and #including the static library's resource.h in the main
application. But the .bin file has to be in the directory of the main
application.
Like I say, it's messy and as such I think only really worth it when you've
got multiple resource files under source control, for instance different
languages created by different people, and they want to test them.

Just another question though - which section of memory has quicker data
access, the global namespace pointer returned by LockResource, or a pointer
to the heap that you allocate and copy the data into?
 
C

Carl Daniel [VC++ MVP]

Bonj said:
OK thanks
I've found you can actually get it to work but it's messy!
I basically did it by adding a blank resource file to the main
application, and then adding the relative path to the static
library's resource file to the 'resource includes' compile-time
directive section of the main app's resource file, and #including the
static library's resource.h in the main application. But the .bin
file has to be in the directory of the main application.
Like I say, it's messy and as such I think only really worth it when
you've got multiple resource files under source control, for instance
different languages created by different people, and they want to
test them.

Yep - that's about the only way to do it with resources. The resource isn't
"in" the stsatic library in any sense of the word, it simply has to be
dragged along with the lib.
Just another question though - which section of memory has quicker
data access, the global namespace pointer returned by LockResource,
or a pointer to the heap that you allocate and copy the data into?

Makes no difference.

-cd
 
B

Bonj

Makes no difference.

It's not as good as stack access speed though?
Just thinking if there's anyway I can make it more likely that this data
would be 'paged in'.
 
C

Carl Daniel [VC++ MVP]

Bonj said:
It's not as good as stack access speed though?
Just thinking if there's anyway I can make it more likely that this
data would be 'paged in'.

There's no difference in memory speed, period. All memory is subject to
paging, including the stack, code, static data, and heap.

-cd
 
B

Bonj

There's no difference in memory speed, period. All memory is subject to
paging, including the stack, code, static data, and heap.

In low memory conditions maybe, but in situations where you've got lots of
things (400KB) stored in the heap, and only a little bit in the stack (a few
bytes), the stack memory is unlikely to get paged out as much as the heap
memory, due to its regularity of use and small size, though, isn't it?
I was under the preception that most of the time an application is running
at near to optimal speed (i.e. isn't hanging) it isn't even using the RAM
chip for the stack, it's just using the processor cache because often the
whole stack will fit in there (and plenty more besides on some fast
processors). Would you not think?
 
C

Carl Daniel [VC++ MVP]

Bonj said:
In low memory conditions maybe, but in situations where you've got
lots of things (400KB) stored in the heap, and only a little bit in
the stack (a few bytes), the stack memory is unlikely to get paged
out as much as the heap memory, due to its regularity of use and
small size, though, isn't it? I was under the preception that most of the
time an application is
running at near to optimal speed (i.e. isn't hanging) it isn't even
using the RAM chip for the stack, it's just using the processor cache
because often the whole stack will fit in there (and plenty more
besides on some fast processors). Would you not think?

The cache is ignorant of the purpose of memory - if a location is being
access frequently, it has as good a chance of being in the cache regardless
of whether it's statck or heap or other.

Whether the stack is more likely to be not-paged out depends a great deal on
execution patterns. It's possible, for example, that an app uses 64K of
stack just about all the time, but occasionally needs 68K. It's likely in
that case that the extra 4K page that gets touched every now & then will get
paged out. Perhaps more likely than an arbitrary page of the heap, perhaps
less likely, depending on the actuall access patterns.

-cd
 
J

Jeff Partch [MVP]

Carl Daniel said:
No, you can't. Not as a resource anyway. Sometimes people will use a

What I think is interesting is that you can add *.res files to a static
library, it's just that there's no way (that I know of) to tell the linker
to use them. Simplistically, you can do this in a makefile...

App.exe : # Whatever
LIB /extract:<<lib409.res Lib.lib
<<NOKEEP
LINK App.obj Lib409.res Lib.lib


But I've always though a LINK switch that does this would be a pretty cool
addition (considering how often this topic comes up)...

LINK /LIBRES:Lib.lib,Lib409.res App.obj Lib.lib
 
W

William DePalo [MVP VC++]

Jeff Partch said:
But I've always though a LINK switch that does this would be a pretty cool
addition (considering how often this topic comes up)...

LINK /LIBRES:Lib.lib,Lib409.res App.obj Lib.lib

I think that the problem is that all of the functions for accessing
resources require the instance handle of the module that contains them.
Static libraries don't get associated with modules until you link them. But
at link time chances are good that another resource script is going to be
associated with a module. Trying to merge the scripts might not be easy.
Worse, if there is a collision in names or IDs then what? Please don't say
name-mangled resources. :)

Regards,
Will
 
C

Carl Daniel [VC++ MVP]

William said:
I think that the problem is that all of the functions for accessing
resources require the instance handle of the module that contains
them. Static libraries don't get associated with modules until you
link them. But at link time chances are good that another resource
script is going to be associated with a module. Trying to merge the
scripts might not be easy. Worse, if there is a collision in names or
IDs then what? Please don't say name-mangled resources. :)

Can you not build a resource file already that has resource ID/name
duplicates?

In any case, I'm with Jeff on this one - if all the linker did was simply
concatenate all the resources together and leave it up to the developer to
manage the IDs, that'd be a great improvement IMO.

-cd
 
W

William DePalo [MVP VC++]

Carl Daniel said:
Can you not build a resource file already that has resource ID/name
duplicates?

Hmm. I don't think so. I just tried to give two dialogs the same name with
VS 2003. The resource script compiled OK (which surprised me) but at link
time I got

xxxx fatal error CVT1100: duplicate resource. type:DIALOG, name:yyyy,
language:0x0409
xxxx fatal error LNK1123: failure during conversion to COFF: file invalid or
corrupt
In any case, I'm with Jeff on this one - if all the linker did was simply
concatenate all the resources together and leave it up to the developer to
manage the IDs, that'd be a great improvement IMO.

With respect to to one's one projects (especially mine <g>) I see value in
that.

I don't know how likely would be, but suppose you've got two static
libraries from two third parties who had built them with resource scripts
attached which duplicated names. You try to link and you can't. That would
be worse (arguably) then the status quo.

Regards,
Will
 
B

Bonj

Yes, right. I suppose in an app (like mine) that uses minimal memory for the
stack (few 100 bytes at most) but 400KB in the global namespace, any
particular small section of memory from that 400KB chunk isn't likely to be
considered 'used frequently', due to its only representing a small part of
the large chunk. But the stack, is used just as often as *any* of this data.
So the stack would *happen* to be more likely to be paged in, but yes, like
you say - not purely on account of it being the stack.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top