通过 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.
应用程序很正常,直接来自向导 MFC 应用程序.我在某处有按钮,这是按钮的处理程序:
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
相关文章