Dialog resources in a static library - c++

I have a problem with dialog and icon resources in my static library.
I have created a MFC static library with Visual Studio 2008.
I am calling Func() in the static library from Win32 application, It tries to launch a MFC dialog in the static library.
When trying to access the resource I am getting afxCurrentResourceHandle is NULL assertion.
I add this line AFX_MANAGE_STATE(AfxGetStaticModuleState()); in the Func() as the first line. But it didn't help.
I need to use only static library. As per requirement, I should not use dll.
Please help me how to launch a dialog in MFC static library from a non MFC application.

The problem here is that a static library doesn't have an 'associated .res file'. If you are trying to migrate a DLL with resources to a static library, then you will need to also 'export' the resource script (its .rc file plus any associated .rc2 files and other referenced resources) to the client program!
So, just as you would have an #include "module.h" line in the .cpp source(s), you will also need an #include "module.rc" in your program's main .rc file (or, at least, in a file that it includes).
Note: Other fixes that folks have tried, like linking explicitly with extra (pre-compiled) .res files won't work! Although the internal structure of a binary .res file is very similar to any other .obj file, the linker will only ever include one!

Related

How to specify path for dlls a dll library uses in c++?

I am using a dll library for my c++ code using LoadLibrary.
HINSTANCE h_dll = LoadLibrary("library1.dll");
When I do this and load the functions, library1.dll seems to use a multiple of other dll files, say library2.dll and library3.dll. So for the program to work, I need to put all 3 dll files in the same directory as the exe file.
The problem happens when I try to put the dll files in a separate directory. I can just directly write the path for library1:
HINSTANCE h_dll = LoadLibrary("C:\\mydir\\library1.dll");
But this doesn't make library1.dll search for files inside C:\\mydir and I get error messages saying library2.dll and library3.dll couldn't be found. So for the program to work, I still need to put the other two library files with the exe.
Is there a way to specify the library path from modifying only the code itself and not the system search path? e.g. sending an argument while loading the library? Or is there a way to modify the dll library files so that it could be placed in separate directories? Or maybe I could create another dll to do these?

utilizing a static library to create an import library

I am interested in using my static lib to create a dll (implicitly linking). which means I need to (in vs2008)
create a dll project that should generate the following:
header file (which have export function declarations. These are simple wrappers to actual functions in the static lib using __declspec(dllexport) which are in the .cpp )
import lib which will be made as a result of creating the dll
the actual dll which is created.
I have made a test program that will utilize the above dll(including the import lib/header files) to test it.
in this I have included all the three items. now the exe compiles/links without issue.
however in the main.cpp when i call the exported functions (with the associated __declspec(dllimport) call it never seems to execute. I am uncertain why this is?
Its almost like the even though the exe can see the exported function in in the dll...the dll cannot call on the code that is in the static lib?
i just cannot answer why my exe can't see the code in the static lib? do i need an archiver/librarian for vs2008 to include all those obj files as part of the import lib?
I am at a loss and am not sure how to test this?
other than just making my static lib directly into a dll. I wanted to try this method. I know i am missing something...i have read all over the place and i am just stuck. There were some threads here that had some people posting something similar but i can't seem to get it. please be as detailed as possible as I am new to this. thanks again.
update 1:
ok so currently i added the extern line to the function prototype and now it sees the exported function from the dll. however, now the only issue left is that:
i can't invoke the function that this exported function (aka wrapper) is trying to call. which happens to be in the static library. how should my exe get visibility to that static library function. I know it can be done because I think there was one other person on this board who was able to make this work.
update 2: my setup is exactly like this questioner...
How to force inclusion of an object file in a static library when linking into executable?
but i am not using explicit linking. i am using implicit linking. my real issue is how to call a static lib function in my dll wrapper which is exported to the exe?
If the app and DLLs are MFC app/dlls, then make sure that the application and all dlls are either "Debug" versions or "release" versions and not a mix.

MFC static library and external rc(resource) file icon loading problem

I have a problem with loading icons from external resource files in main application. I'll try to explain how application is set right now. The resources of the main application includes external dialog *.rc and appropriate *.h. And linker includes dialog implementation (CDialog/CFormView) which resides in external static library *.lib.
External *.rc has:
IDI_MY_ICON ICON "my_icon.ico"
External *.h has:
#define IDI_MY_ICON 10000
Dialog implementation in static lib *.cpp has:
HICON MyDialog::GetNeededIcon()
{
return AfxGetApp()->LoadIcon(IDI_MY_ICON);
}
I thought that it should reside in the same folder as external *.rc file is. I also tried to place them in the main app folder, but application still doesn't load them. Could someone explain me where my_icon.ico is searched in?
P.S. - Contents of files are only examples here.
AfxGetApp()->LoadIcon(IDI_MY_ICON); tries to load the icon from the current app (exe).
If you want to load it from another module, you will either have to remember the handle returned from LoadLibrary, or call GetModuleHandle to retrieve it again.
Your .rc file is compiled by rc.exe to embed the icon in your executable. rc.exe uses the include path to find the resources. This is specified by either the INCLUDE environment variable or by using /I option to rc.exe. If "my_icon.ico" doesn't work, try moving the file or change the include path.
Clarification:
rc.exe compiles .rc files into .res, but its the linker that does the actual embedding into the executable.

Resources in a static lib file - MFC

MFC is failing to launch my dialog boxes, it seems, because it can't find the resource identifiers. The dialog boxes are in a separate .lib file (so it has a separate .rc file, which, I'm assuming, somehow conflicts with the one in my .exe file). How should I be handling this situation?
In the .rc file for the .exe file, add a line like this:
#include "YourLibResourceFile.rc"
Then, in the .exe's project settings, add an additional include directory to where YourLibResourceFile.rc is, in Resources/Additional Include Directories.
You can't store resources (.rc files contents) in a static library. And since you can have only one "main" .rc file, all other .rc files mst be included in that one using an #include statement, such as explained by Smashery (Edit: Oh! Smashery, you are the OP!).
Make sure all your resource IDs are unique.

LoadString, static library and executables

My project is set up so all the framework code and modules are compiled to a static .lib (let's call it framework.lib), and many test projects use framework.lib and compile to executable files.
For error handling, I'm trying to put the resource strings in framework.rc (part of the framework.lib project) and load the strings in the executable files. However, LoadString() just fails. Using GetLastError() / FormatMessage() I get the following message:
"The specified resource type cannot be found in the image file."
Here is how I call LoadString, which returns 0:
char szString[256];
int iNbOfChars = LoadStringA(GetModuleHandle(NULL), iStringID, szString, 256);
Should what I do be failing because the resource is not defined in the app, but in the lib? If so, any suggestions so I can have a centralized resource file?
Static libraries are just concatenations of .OBJ files - they don't have features like resources. To do this you need to put the resources in DLL.
You can't put resources into .lib files. (I wish you could). You have to keep the .rc files around and include them into the app's .rc file when you link to the lib.
And because of that, you have to make sure that none of the resource id's used by the .lib are also used by the app. It's a whole mess, but there is no better solution if you use .rc files for your strings. and stick with microsoft's tools.
About couple of years ago I got so frustrated with this limitation, that I went off and build a tool that would turn a compiled resource file (.res) into a .obj file, so I could include it into my lib. Of course, when you do that, you can't use LoadString anymore, but it turns out that writing your own code to parse a hunk of .res data and find the strings isn't really that hard. So my current solution to put strings in libraries is
create framework.rc
compile it into framework.res
turn framework.res into framework.obj which contains external symbols
const BYTE framework_res[];
const size_t framework_res_size;
use MyLoadString(framework_res, framework_res_size, iStringId, sz, 256) instead of LoadString when fetching strings in the library.
One advantage of doing it this way turned out to be that when I wrote my own LoadString, I could return a pointer to the resource string, rather than copying it. so my actual LoadString function looks like this.
LPCWSTR MyFindString(framework_res, framework_res_size, iStringId);
If you compile your .rc file with the /n option, it will null terminate all of the strings.
You can use an #include directive in the app's resource file to include the lib's resource file.
Resources are only allowed at the output (EXE) level and cannot be embedded into a .Lib.
AFAIK you can not add resources to a static library - you have to either compile them into a DLL to share or directly into the Application.
You could share the .rc from a central location and compile that into the application itself.
The obvious way to centralize the resources would be to create a DLL that contains the resources. Then you can use LoadString and such just like if the resource was in the executable, except for the minor detail that you need to specify the correct module handle instead of NULL.