通过 LoadLibrary 调用 DLL 时 MFC 状态无效

MFC state invalid when DLL called through LoadLibrary(通过 LoadLibrary 调用 DLL 时 MFC 状态无效)

本文介绍了通过 LoadLibrary 调用 DLL 时 MFC 状态无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 MFC 并动态链接 DLL 与 LoadLibrary.当应用程序调用 DLL 时,我似乎无法正确获取 MFC 状态,并且 DLL 在同一个调用中回调.最终,它会导致大量断言.

i'm fighting with MFC and dynamicly linking DLLs with LoadLibrary. It seems that I cannot get the MFC state right when the app calls DLL, and the DLL calls back in the same call. Ultimately, it leads to tons of asserts.

这是我正在做的代码模型.

Here is code mock-up of what i'm doing.

  1. 应用程序很正常,直接来自向导 MFC 应用程序.我在某处有按钮,这是按钮的处理程序:

  1. The application is just normal, straight from the wizard MFC app. I've got button somewhere and this is the button's 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);
                }
        }
}

  • 那么'PluginMFCShared'看起来像这样:

  • Then the '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();
    }
    

  • 所以,这个想法是应用程序 (CTheApp1View::OnTestRun1) 加载一个库并调用一个直接传入回调指针的函数.在继续之前,库将使用该回调从应用程序中执行某些操作.

    So, the idea is that the app (CTheApp1View::OnTestRun1) loads a library and calls a function directly passing in a callback pointer. The library would use that callback to execute something from the app before continuing.

    我认为 AFX_MANAGE_STATE 会处理 MFC 状态,但似乎还有更多工作要做.

    I thought AFX_MANAGE_STATE will take care of the MFC state, but there seem to be something more that needs to be done.

    可以在以下位置找到一个测试项目(确保将 TheApp1 项目设置为启动项目):SystemOfPlugins.zip

    A test project could be found at (make sure TheApp1 project is set to be the start-up project): SystemOfPlugins.zip

    有什么想法吗?

    感谢您的任何建议.

    推荐答案

    这是另一个建议.在您的 App 变量中,添加一个名为 m_pModuleState 的 AFX_MODULE_STATE* 变量,并在 InitInstance 函数的末尾对其进行初始化,

    Here's another suggestion. In your App variable, add an AFX_MODULE_STATE* variable named m_pModuleState, and initialize it at the end of the InitInstance funciton,

    m_pModuleState = AfxGetModuleState();
    

    修改你的回调函数,在打开对话框之前设置应用程序状态,然后在退出函数之前设置回原来的状态

    Modify your callback function to set the application state before opening the dialog, and then set back the original 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 keep 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();
    }
    

    这样,您可以在插件中调用 AFX_MANAGE_STATE,但是当某些插件调用回调函数时,请确保设置应用程序的状态,以便它可以找到好的对话框资源并执行特定于状态的函数

    This way, you would call AFX_MANAGE_STATE in your plugins, but when some of the plugin make a call to the callback function, you make sure to set the app's state so it can find the good dialog resources and execute state-specific functions

    这篇关于通过 LoadLibrary 调用 DLL 时 MFC 状态无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

    本文标题为:通过 LoadLibrary 调用 DLL 时 MFC 状态无效