MFC扩展dll资源加载问题
MFC extension dll resources loading problems
我已经构建了以下配置:
- A) 具有2个MFC对话框的MFC扩展DLL
- B) 使用dll A函数的MFC常规dll
- C) win32应用程序(NON MFC)从DLL B调用函数
当从DLL B调用函数(内部调用DLL A的函数以显示对话框)时,由于找不到资源,会发生错误。
我已经找到了确切的根本原因,主要原因似乎是模块上下文设置为调用dll B,而不是包含对话框资源的dll A。
在DllMain中,初始化是按照MSDN中的描述进行的:
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
Hinstance = hInstance; //save instance for later reuse
// Extension DLL one-time initialization
if (AfxInitExtensionModule(extensionDLL,hInstance) == 0)
{
AfxMessageBox("Error on init AfxInitExtensionModule!");
return 0;
}
// Insert this DLL into the resource chain
new CDynLinkLibrary(extensionDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
Release();
}
return 1;
}
我发现的一个解决方法是存储从DLLMain:extern"C"int APIENTRY DLLMain接收的hInstance参数(hInstanceh实例,DWORD dwReason,LPVOID lpReserved)当函数被调用时,在DLL A内部,我保存当前句柄并设置新句柄从DllMain:接收的句柄
DLL A function1(............)
{
HINSTANCE HinstanceOld = AfxGetResourceHandle();
AfxSetResourceHandle(CErrohInstance);
.......
//display dialog
.....
AfxSetResourceHandle(HinstanceOld);
}
通过使用此解决方案,它仍然会导致断言,但会显示对话框。
解决这个问题的正常方法应该是什么?
您必须将扩展DLL的资源插入到常规DLL的资源链中,而不是EXE。只需在扩展DLL中创建一个函数,并在常规DLL的InitInstance方法中调用它,如下所示:
void initDLL()
{
new CDynLinkLibrary(extensionDLL);
}
你说的是"模块上下文",但实际上终端技术是"模块状态"。
AFAICS这是相对标准的(即最频繁出现的)MFC模块状态相关用例,即:通过回调/公共导出API进入内部实现区域。
AFX_MANAGE_STATE直接提到了这个用例:"如果你在DLL中有一个导出的函数"
此时,当前活动的模块状态是调用方的状态,而不是实现范围内所需的状态。由于实现范围知道它需要一个不同的模块状态(而它是所知道的,哪一个是正确的!),它需要临时切换到正确的状态,以实现在正确的实例范围内进行任何与模块状态相关的查找(确切地说:资源实例查找)。
这不需要通过AfxSetModuleState()手动完成,而是通过AFX_MANAGE_STATE宏的适当的生存期范围(确保在任何可能存在的取消点进行适当的销毁,无论是返回点还是异常点)机制来完成。
IOW,实现可能需要非常类似以下内容:
BOOL MyPublicAPIOrCallback()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // ensure locally expected module state within this externally-invoked handling scope
some_handling_which_does_resource_lookup_or_whatever;
}
不知道你是否已经找到了解决方案,如果没有,你可以尝试使用
AfxFindResourceHandle
在访问Dll A.中有问题的资源之前。
我已经在DLLMain中添加了这几行,现在我在使用DLL调用的其他DLL中的资源(如对话框)时没有问题。这是代码:
static AFX_EXTENSION_MODULE CODIAbantailDLLDLL = { NULL, NULL };
AplicacionBase theApp;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Quitar lo siguiente si se utiliza lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
// ******** VERY IMPORTANT ***********************
// IF you doesn't put this, when you call other DLL that has
// its owns resources (dialogs for instance), it crash
CoInitialize(NULL);
AfxWinInit(hInstance, NULL, ::GetCommandLine(), 0);
AfxEnableControlContainer();
//**************************************************
TRACE0("Inicializando CODIAbantailDLL.DLLn");
// Inicialización única del archivo DLL de extensión
if (!AfxInitExtensionModule(CODIAbantailDLLDLL, hInstance))
return 0;
new CDynLinkLibrary(CODIAbantailDLLDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("Finalizando CODIAbantailDLL.DLLn");
// Finalizar la biblioteca antes de llamar a los destructores
AfxTermExtensionModule(CODIAbantailDLLDLL);
}
return 1; // aceptar
}
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- Qt Visual Studio 2015 加载项编译问题
- 使用 sv hup SIGHUP 信号重新加载配置时出现问题
- 从文件问题加载纹理 Android NDK 和 OpenGL
- 将文件从 iOS 应用程序加载到 C++ 对象中/<iostream>iOS 上的问题
- 加载带有stb_image的图像时出现问题
- 我如何加载多个脚本而没有变量问题
- 问题在具有依赖性时从其他路径上加载DLL的DLL
- 关于加载COM Tlb文件的一些问题
- 问题:Windows 10:QMYSQL驱动程序未加载
- 部署时QT SQLITE问题:未加载驱动程序
- 从中加载字符串时出现 sscanf 问题
- 协议缓冲区;将数据保存到磁盘并重新加载问题
- 断开命名管道(在加载表上)上的 SybaseIQ 问题
- 问题4:如何加载()和存储()
- 与OsX相比,Windows上的GUI加载问题
- MFC扩展dll资源加载问题
- DLL 无法加载:0x8007007E找不到模块。不确定导致此依赖项问题的原因
- 将简单网格加载到 OpenGL 中时遇到问题
- 如何调试静态依赖项加载问题