Resource Synchronization with a LoadLibrary

Dear Experts ,
I'm trying to design the following architecture :

Client DLL -> Factory DLL -> Provider DLL

The client DLL  is an MFC C++ DLL that containts a LoadLibrary on the Factory DLL.

The Factory DLL only create an instance of the Provider DLL objects and returns a pointer to that new object. then the client use that pointer to call different method in the Provider.DLL object.

when I call a method of the Provider DLL object , it works but as soon as the this object does a loadstring in the string table I get an ASSERT in the AfxGetResourceHandle.  What do I need to do to synchronize the resource between th modules?


Client DLL:
void C2020XmlData::SifXml()
{	
	HINSTANCE hDll;
	hDll = LoadLibrary(_T("Factory.dll"));//
	LPFNDLLFUNC1 testToTo;
	bool bIsOk = FALSE;
	
	if(hDll != NULL)
	{
		AfxSetResourceHandle(hDll); 
		testToTo = (LPFNDLLFUNC1)GetProcAddress(hDll, "DllGetObject");
 
		if(testToTo != NULL)
		{
			ISifCatalog* pMyObject = (testToTo)();
			if(pMyObject != NULL)
			{
				CString scatName("D:\\Repository\\als\\A32\\A32.top");
				pMyObject->SetWriteMode(1);	 
				pMyObject->SetFileCatName(scatName);
				pMyObject->SetremoveNulPrice(true);
				pMyObject->SetremoveNulDimensions(true);
				pMyObject->SetremoveNulDescription(true);
				pMyObject->SetremoveIdenticalPO(true);
				pMyObject->SetpushOptionPriceToProduct(true);
				pMyObject->SetwriteIgnoredSifCodes(true);
 
				pMyObject->Read();
 
				AfxMessageBox("Done !!!!");
				FreeLibrary(hDll);
		
			}
			
		}
		
	}
}
 
Factory DLL:
 
extern "C"
__declspec(dllexport) ISifCatalog* DllGetObject()
{
	AFX_MANAGE_STATE(AfxGetAppModuleState());
	ISifCatalog* pObj = static_cast<ISifCatalog*>(new SifCatalog);
	return pObj;
}
 
Provider object contain method that are called in the Client Object.

Open in new window

toy187Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mahesh1402IT ProfessionalCommented:
How you are loading string resource from DLL ?What you need to do here is temporarily set the resource handle of your resource DLL as current, and then call LoadString and then restore resource handle.

e.g.


 HINSTANCE    hOldInstance = AfxGetResourceHandle();
 AfxSetResourceHandle( hMyResourceDllInstance );


 CString strTest;
 strTest.LoadString( IDS_MY_EXTERNAL_RESOURCE_STRING );


 AfxSetResourceHandle( hOldInstance );

--How are you loading ???

-MAHESH
0
jkrCommented:
I'd rather try to access the strings by specifying the module instance directly to minimize the confusio of MFC's chained resource list, i.e. instead of using a CString helper, use the Win32 API:
char buffer[255];
 
::LoadString(hDll,IDS_MYSTRING1,buffer,255);

Open in new window

0
toy187Author Commented:
thank you all for your comments , the thing is that the module that  does the loadstring is part of another MFC application that works , I can't modify the way it load the resource. After doing some testing , I realize that I don't have the assert with a new and empty MFC application in which I call my object the same way. The module in which I'm trying to create this is loaded in a mfc app with  the ATL Class Factory. Maybe there is something to be done in my new imported module in order to sychronize the resources?
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

jkrCommented:
What asseretion (file, line) exactly are you getting?
0
toy187Author Commented:
It is asserting in the  C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxwin1.inl
line 26
 _AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle()
       { ASSERT(afxCurrentResourceHandle != NULL);

So clearly the current Ressource Handle is null even though I did the  AfxSetResourceHandle(hDll); and the AFX_MANAGE_STATE(AfxGetAppModuleState());
0
jkrCommented:
Is 'C2020XmlData::SifXml()()' called directly also or only via the constructor?
0
itsmeandnobodyelseCommented:
>>>>> AfxSetResourceHandle(hDll);

The AfxSetResourceHandle would be used if you want to access resources which were built with that dll where the hDll is the instance handle of.

E. g. if you have a x.dll which has a resource file x.rc, and have y.exe which loads the x.dll with hxdll = LoadLibrary, then after calling AfxSetResourceHandle(hxdll), the y application could load strings from the x.rc.

As far as I see, you have a far different case above:

- the client dll loads the factory dll
- the factory dll loads the provider dll statically
- the client dll resets its resource handle by calling AfxSetResourceHandle
- an exported method in the provider dll calls LoadString

Obviously, the last call cannot access a resource loaded with the factory dll as each dll has its own resource handle. Or differently said, when you call AfxSetResourceHandle in the client dll, it has *no* influence on the resource handle stored in the provider dll. If you want to change that, you need to provide a method in the provider dll where you can pass a different handle and where the method in the provider dll calls AfxSetResourceHandle. Note, I don't say that this would work, as the Afx methods partially rely on static and global variables which can't be exchanged between executables. A much better approach is to have a common resource dll whcih was loaded by all dlls and where each dll calls the AfxSetResourceHandle separately (and independently).

Regards, Alex
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DanRollinsCommented:
Perhaps more succinctly:  It appears that you need to make changes in the Provider DLL.   Is that possible?

In particular, it appears that the Provider DLL does not do the normal setup that would initialize the global value of afxCurrentResourceHandle.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.