How to Load a Custom Binary Resource in a Vc++ Static Library as Part of a Dll

VC++ resources in a static library

It can be done, but it's quite painful: You can't do it by simply linking with the static library.

Consider this: resources are embedded in an EXE or DLL. When some code in the static library calls (e.g.) LoadIcon, it'll get the resources from the EXE or DLL that it's linked with.

So, if your static library requires resources to be available, you've got a couple of options:

  1. You can have the library build them on the fly, and then use (e.g.) CreateDialogIndirect. See Raymond Chen's "Building a dialog template at run-time".
  2. You can have them embedded in the library as simple arrays (i.e.) char my_dialog_resource[] = { .... };, and then use (e.g.) CreateDialogIndirect. You'll probably need to find (or write) a utility that converts from .RES files to .CPP files.
  3. You can ship the LIB file with a resource script (.RC file) and corresponding header file. You then #include them as relevant. You'll need to reserve a range of resource IDs for the LIB to use, so that they don't collide with those of the main EXE or DLL. This is what MFC does when used as a static library. Or you can use string resource IDs (this doesn't work for STRINGTABLE resources).
  4. Your static library can ship with a separate resource DLL.

Is there a way to interleave static library and dependent dll compilation (MSVC)?

Unless you have edited the library's source code, MSVC doesn't compile it (again). But if you have edited it, then obviously you will have to one way or the other (well if you want the features to be in the build). If you edit just the dependent, unless your not talking about circular dependencies, the dependencies wont be recompiled.

When using option 1, Visual C++ waits until all the libraries are compiled before it initiates the dll compilation. In my view this is a waste since these are only link time dependencies.

Yes, you have to build its dependencies before compiling the dependent. What if you have something in the dependent which is something you added recently, after the prior build? You'll have to compile the dependency again right?..

When using the second option, I am not sure that Visual C++ will wait until the dependencies compilation is complete before attempting to link them.

Nope Visual Studio doesn't check if the library exists before compiling it. But then, you have to make sure that the dependencies are compiled before the dependent. Yet again, if you have something new in the dependency, you'll have to compile it.

So is it possible to specify that a static library dependency is a link time dependency only and interleave static libraries and dependent dll compilation?

That's how static libraries work. Libraries are linked at link time, not compile time. The way Visual Studio builds the dependencies is that they maintain a dependency graph. When compiling, it checks if a library needs to be recompiled and if not, leave it.

MSVC also doesn't compile .obj files which aren't changed. So if you want to speed up build time, move (movable) header definitions to source files so that specific source file will be recompiled, rather than all the included source files (the source files which include the header file).

The bottom line is, if your working with a lot of libraries, or even one big library, all the edited sources will be recompiled. Multithreading the build is the only way to speed up compilation. Or you could invest in a dedicated machine to compile it for you (server or something).

how to access files in a resource dll

Once again, I found the solution to the problem.
The syntax "res://C:\Program Files\MyApp\MyDLL.dll/myfile.htm" is correct but somehow it was not working for me. Then I changed it ti "res://C:\Program Files\MyApp\MyDLL.dll/100" where 100 is the 'value' of the resource (every resource in a resource file has an ID and a value). To find out what your resource value is in VS 2005, switch to resource view, right click on the resource file that you want to know the value of and select 'resource symbols'.

Load resource as byte array programmaticaly in C++

To obtain the byte information of the resource, the first step is to obtain a handle to the resource using FindResource or FindResourceEx. Then, load the resource using
LoadResource. Finally, use LockResource to get the address of the data and access SizeofResource bytes from that point. The following example illustrates the process:

HMODULE hModule = GetModuleHandle(NULL); // get the handle to the current module (the executable file)
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(RESOURCE_ID), RESOURCE_TYPE); // substitute RESOURCE_ID and RESOURCE_TYPE.
HGLOBAL hMemory = LoadResource(hModule, hResource);
DWORD dwSize = SizeofResource(hModule, hResource);
LPVOID lpAddress = LockResource(hMemory);

char *bytes = new char[dwSize];
memcpy(bytes, lpAddress, dwSize);

Error handling is of course omitted for brevity, you should check the return value of each call.



Related Topics



Leave a reply



Submit