MFC state is invalid when calling DLL through LoadLibrary

I fight with MFC and dynamically link DLL with LoadLibrary. It seems that I cannot get the MFC state correctly when the application calls the DLL and the DLL call calls the same call. Ultimately, this leads to many statements.

Here is the layout code of what I'm doing.

  • The application is just fine, right from the MFC wizard application. I have a button somewhere, and this is a button handler:

    void callback() { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CDialog1 dlg; dlg.DoModal(); } typedef void (*TPluginMainFunc)(void*); void CTheApp1View::OnTestRun1() { static HMODULE hPluginMFCShared = LoadLibrary( _T("PluginMFCShared") ); if ( hPluginMFCShared ) { TPluginMainFunc func = (TPluginMainFunc) GetProcAddress( hPluginMFCShared, "plugin_main" ); if ( func ) { func(callback); } } } 
  • Then "PluginMFCShared" looks like this:

     typedef void (*TFunc)(); extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); func(); CDialog1 dlg; dlg.DoModal(); } 

So the idea is that the application (CTheApp1View :: OnTestRun1) loads the library and calls the function directly passed by the callback pointer. The library will use this callback to execute something from the application before continuing.

I thought AFX_MANAGE_STATE would take care of the state of the MFC, but there seems to be something else to do.

The test project can be found in (make sure that TheApp1 project is installed as the initial project): SystemOfPlugins.zip

Any ideas?

Thanks for any suggestions.

+4
source share
3 answers

Here is another suggestion. In the App variable, add the AFX_MODULE_STATE * variable named m_pModuleState and initialize it at the end of the InitInstance function,

 m_pModuleState = AfxGetModuleState(); 

Change the callback function to set the state of the application before opening the dialog box, and then set the initial state before exiting the function

 void callback() { //Get the original state AFX_MODULE_STATE* pOriginalState = AfxGetModuleState(); //Set the mfc state AfxSetModuleState(((CTheApp1App*)&theApp)->m_pModuleState); //Do stuff here CDialog1 dlg; dlg.DoModal(); //Set the mfc state back to its original state AfxSetModuleState(pOriginalState); } 

And save your plugin as it was in your example

 extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); func(); CDialog1 dlg; dlg.DoModal(); } 

Thus, you should call AFX_MANAGE_STATE in your plugins, but when any of the plugins makes a callback function call, you must set the state of the application so that it can find good dialog resources and perform state-dependent functions

+2
source

I looked at your code and I got it by modifying 2 functions:

in pluginMFCShared.cpp, I called AFX_MANAGE_STATE after calling the func () function

 extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func) { func(); AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CDialog1 dlg; dlg.DoModal(); } 

In theapp1view.cpp, I deleted AFX_MANAGE_STATE

 void callback() { CDialog1 dlg; dlg.DoModal(); } 

Now two dialogs appear one after another

0
source

Are you building a dll with _LIB preprocessor flag? If yes, check if you really need to - the whole concept of "MFC dll" is outdated, there is no reason to use it anymore. Then forget about all AFX_MANAGE_STATE stuff. In your dll, save the HMODULE of the dll library, which is passed to DllMain, and use :: AfxSetResourceHandle () to the correct value before each use of CDialog or similar. Wrap it in a smart pointer class that sets the correct resource descriptor and resets it to the old (= main application, usually 0x4000 ...) when the object goes out of scope.

For all purposes, where you can pass a resource descriptor directly (LoadString, etc.), you don’t even need to touch the global descriptor.

Much easier to work and much more transparent. The resource handle is the only one that has to do with MFC status in MFC versions, since VS6 is anyway.

0
source

Source: https://habr.com/ru/post/1386334/


All Articles