我们的MFC项目分为一个EXE和几个DLL,这也可能包含MFC-Dialogs。为了加载这样的对话框,DLL包含导出的DLL函数。我们有麻烦为对话框加载正确的资源。
目前,功能看起来像这样:
extern "C" __declspec( dllexport ) int ShowDialog()
{
HINSTANCE hInstOld = AfxGetResourceHandle();
AfxSetResourceHandle(DXFDECDLL.hResource);
CMyDllDialog dlg;
AfxSetResourceHandle(hInstOld);
dlg.DoModal();
return 1;
}
它在(大多数情况下),但似乎很糟糕。功能 afxsetResourceHandle
设置当前AFX_MODULE_STATE的资源句柄,此模块状态是EXE之一。如果其他一些线程在此期间尝试从资源加载字符串,则将失败。
我认为,我们必须更改主动模块状态,但我不知道如何。
我已经阅读了以下文章,但其公会失败了。
- 如果我将afx_module_state似乎不会自动更改代码> loadLibrary 并通过功能指针调用该方法。我需要编辑自动生成的
dllmain
吗?
- 如果我尝试调用
afx_manage_state(afxgetStaticModulestate());
在我的函数showdialog中,我会得到一个链接器错误link2005:“ _dllmain @12在dxfdec.obj中已定义在dxfdec.obj中
,这是一个最小示例,它会生成链接器错误。它由Visual Studio代码生成器生成。我刚刚添加了函数 myFunction
#include "pch.h"
#include "framework.h"
#include <afxwin.h>
#include <afxdllx.h>
static AFX_EXTENSION_MODULE MFCLibrary3DLL = { false, nullptr };
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
if (!AfxInitExtensionModule(MFCLibrary3DLL, hInstance))
return 0;
new CDynLinkLibrary(MFCLibrary3DLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
AfxTermExtensionModule(MFCLibrary3DLL);
}
return 1; // OK
}
extern "C" __declspec(dllexport) int MyFunction()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return 0;
}
Our MFC-project is split into an exe and several dlls, which may also contain MFC-dialogs. For loading such a dialog, the dll contains an exported dll function. We have troubles loading the right resources for the dialog.
At the moment, the function looks like this:
extern "C" __declspec( dllexport ) int ShowDialog()
{
HINSTANCE hInstOld = AfxGetResourceHandle();
AfxSetResourceHandle(DXFDECDLL.hResource);
CMyDllDialog dlg;
AfxSetResourceHandle(hInstOld);
dlg.DoModal();
return 1;
}
It is working (most of the time), but seems to be bad. The function AfxSetResourceHandle
sets the resource handle of the current AFX_MODULE_STATE and this module state is the one of the exe. If some other thread tries to load a string from the resource in the meantime, it will fail.
I think, we have to change the active module state, but I don't know how.
I have read the following article, but its guildlines fail.
https://learn.microsoft.com/en-us/cpp/mfc/tn058-mfc-module-state-implementation?view=msvc-170
- The AFX_MODULE_STATE does not seem to be changed automatically, if I load the DLL with
LoadLibrary
and calling the method via a function pointer. Do I need to edit the automatically generated DLLMain
?
- If I try to call
AFX_MANAGE_STATE(AfxGetStaticModuleState());
in my function ShowDialog, I get a linker error LINK2005: "_DLLMain@12 is already defined in DXFDEC.obj"
Concerning the comment of @IInspectable, here is a minimal example, which generates a linker error. It is generated by the Visual Studio code generator. I have just added the function MyFunction
#include "pch.h"
#include "framework.h"
#include <afxwin.h>
#include <afxdllx.h>
static AFX_EXTENSION_MODULE MFCLibrary3DLL = { false, nullptr };
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
if (!AfxInitExtensionModule(MFCLibrary3DLL, hInstance))
return 0;
new CDynLinkLibrary(MFCLibrary3DLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
AfxTermExtensionModule(MFCLibrary3DLL);
}
return 1; // OK
}
extern "C" __declspec(dllexport) int MyFunction()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return 0;
}
发布评论