Hi,
I'm developing a project which contains a binary and couple of DLLs.
One of the DLLs needs the locally available resources (one that no other DLLs or binary needs).
Now, what I did
The DLL project are the mimics of the DLL project from the sample. So no Resources are available.
I added the resource file to that folder with the appropriate changes.
But trying to compile I see that no resource compiler is invoked.
And trying to run - I am getting an assert about failing to load the resource.
Am I wrong? Should I pt all the resources inside the binary resource file?
Or I did everything correctly and just missed a step?
Please advise.
Thank you.
What is the best way to work with .rc in DLL project
Re: What is the best way to work with .rc in DLL project
What does it mean? Did you add the .rc file not only to the disk folder but to the project (MSVC, C:B, makefile...) as well? If you are not sure whether the resource is being embedded, use Resource Hacker and check the DLL. If the resource is there and your code fails to load it, make sure you use a correct way to load it (see e.g. here where one possible mistake is discussed). If the resource is in the DLL, but you still cannot load it, post the relevant parts of the .rc file and the code attempting to load the resource.
Re: What is the best way to work with .rc in DLL project
Hi, PB,
Yes the resource file is added to both disk and the DLL project (using MSVC 2017 Community).
The reason I am talking about resource compiler is because when I try to change that file and rebuild, I don't see the resource compiler to be executed to rebuild the rc file.
I will try to use Resource Hacker - thank you for the pointer.
Thank you.
Yes the resource file is added to both disk and the DLL project (using MSVC 2017 Community).
The reason I am talking about resource compiler is because when I try to change that file and rebuild, I don't see the resource compiler to be executed to rebuild the rc file.
I will try to use Resource Hacker - thank you for the pointer.
Thank you.
Re: What is the best way to work with .rc in DLL project
Hi, PB,
From the .rc file:
From the .cpp file:
From the Resource Hacker I see that the resource is called BOLD, but I think this is just the Windows not distinguishing the upper/lower-case.
Thank you.
From the .rc file:
Code: Select all
bold RCDATA "res/gui/bold.png"
Code: Select all
m_styleBar->AddTool( 303, _( "Bold" ), wxBITMAP_PNG( bold ), wxNullBitmap, wxITEM_NORMAL );
Thank you.
Re: What is the best way to work with .rc in DLL project
Sorry for the stupid questions, but they are mandatory. ;)
Can you load other resources or all resources fail to load?
Did you init the PNG image handler?
Is "bold" not defined anywhere and assigned a numeric value (see the link in my previous post)?
What exactly is the assert message? If it is not helpful, I suggest stepping through the code to see where and why exactly the call fails.
Can you load other resources or all resources fail to load?
Did you init the PNG image handler?
Is "bold" not defined anywhere and assigned a numeric value (see the link in my previous post)?
What exactly is the assert message? If it is not helpful, I suggest stepping through the code to see where and why exactly the call fails.
Re: What is the best way to work with .rc in DLL project
Hi, PB,
What's interesting is that the call to ::FindResource(), which uses hInstance is using the main application one and not the one from DLL. At least that's what MSVC debugger shows.
The DLL is initialized as:
[coede]
#ifdef __WXMSW__
WXDLLIMPEXP_BASE void wxSetInstance( HINSTANCE hInst );
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
lpReserved = lpReserved;
hModule = hModule;
#ifndef WXUSINGDLL
int argc = 0;
char **argv = NULL;
#endif
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
#ifdef WXUSINGDLL
wxInitialize();
#else
wxSetInstance( (HINSTANCE) hModule );
wxEntryStart( argc, argv );
if( !wxTheApp || !wxTheApp->CallOnInit() )
{
wxEntryCleanup();
if( wxTheApp )
wxTheApp->OnExit();
return FALSE;
}
#endif
break;
case DLL_PROCESS_DETACH:
#ifdef WXUSINGDLL
wxUninitialize();
#else
if( wxTheApp )
wxTheApp->OnExit();
wxEntryCleanup();
#endif
break;
}
return TRUE;
}
#endif
class MyDllApp : public wxApp
{
public:
bool OnInit()
{
return true;
}
int OnExit()
{
return 0;
}
};
IMPLEMENT_APP_NO_MAIN(MyDllApp);
[/code]
which is basically the code from the dll sample.
Maybe I should just try to modify the sample?
As a workaround I will try to see if its possible to add the PNG to the main .rc file...
Thank you.
They are not stupid - as you say "they are mandatory"
In the DLL there is only one "bold" PNG image. There is no other resources in other DLLs - just main resource file in the main binary.
Yes, I did - in the main binary though. Surprisingly enough it is found inside the DLL.
No, it is not. I checked.
I did step thru the code.
What's interesting is that the call to ::FindResource(), which uses hInstance is using the main application one and not the one from DLL. At least that's what MSVC debugger shows.
The DLL is initialized as:
[coede]
#ifdef __WXMSW__
WXDLLIMPEXP_BASE void wxSetInstance( HINSTANCE hInst );
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
lpReserved = lpReserved;
hModule = hModule;
#ifndef WXUSINGDLL
int argc = 0;
char **argv = NULL;
#endif
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
#ifdef WXUSINGDLL
wxInitialize();
#else
wxSetInstance( (HINSTANCE) hModule );
wxEntryStart( argc, argv );
if( !wxTheApp || !wxTheApp->CallOnInit() )
{
wxEntryCleanup();
if( wxTheApp )
wxTheApp->OnExit();
return FALSE;
}
#endif
break;
case DLL_PROCESS_DETACH:
#ifdef WXUSINGDLL
wxUninitialize();
#else
if( wxTheApp )
wxTheApp->OnExit();
wxEntryCleanup();
#endif
break;
}
return TRUE;
}
#endif
class MyDllApp : public wxApp
{
public:
bool OnInit()
{
return true;
}
int OnExit()
{
return 0;
}
};
IMPLEMENT_APP_NO_MAIN(MyDllApp);
[/code]
which is basically the code from the dll sample.
Maybe I should just try to modify the sample?
As a workaround I will try to see if its possible to add the PNG to the main .rc file...
Thank you.
Re: What is the best way to work with .rc in DLL project
I am just guessing here.
My guess (based on skimming wxWidgets source) would be that this version wxEntryStart
is intended for console applications and it overwrites the DLL instance you set by wxSetInstance() before. There are also these two overloads for MSW GUI applications
It also seems that wxWidgets DLL sample initializes wxWidgets differently than you do?
But again, I am just guessing here and can be entirely wrong.
My guess (based on skimming wxWidgets source) would be that this version wxEntryStart
Code: Select all
wxEntryStart( argc, argv );
Code: Select all
WXDLLEXPORT bool wxEntryStart(HINSTANCE hInstance,
HINSTANCE WXUNUSED(hPrevInstance),
wxCmdLineArgType WXUNUSED(pCmdLine),
int nCmdShow)
WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
HINSTANCE WXUNUSED(hPrevInstance),
wxCmdLineArgType WXUNUSED(pCmdLine),
int nCmdShow)
But again, I am just guessing here and can be entirely wrong.