链接使用MFC的常规DLL时,MFC应用程序断言失败

链接使用MFC的常规DLL时,MFC应用程序断言失败,dll,mfc,assert,Dll,Mfc,Assert,我正在将一个旧的OWL应用程序迁移到MFC。有一个拥有主对话框和控件的主库,我开始为旧的OWL编写一个替代类MFC,比如TDialog[inherits from CDialogEx],TEdit。。。。。我从OWL添加了所有需要的类,现在我的库构建成功了 我创建了一个新的MFC应用程序[用于测试库],我从dll中导出了一个函数[SowDialogue],用于该应用程序,我将.lib的dll添加到MFC应用程序中,我调用该函数以显示一个简单的对话框,构建成功,但是在第一次启动时,应用程序会失败,

我正在将一个旧的OWL应用程序迁移到MFC。有一个拥有主对话框和控件的主库,我开始为旧的OWL编写一个替代类MFC,比如TDialog[inherits from CDialogEx],TEdit。。。。。我从OWL添加了所有需要的类,现在我的库构建成功了

我创建了一个新的MFC应用程序[用于测试库],我从dll中导出了一个函数[SowDialogue],用于该应用程序,我将.lib的dll添加到MFC应用程序中,我调用该函数以显示一个简单的对话框,构建成功,但是在第一次启动时,应用程序会失败,并显示以下消息

我单击了retry和break,以获取导致断言的行,即该行

因此,问题在于资源。当我与库链接时,MFC无法获得正确的资源模块

我认为这是因为如果我必须使用MFC扩展库,我使用一个使用MFC并共享MFC对象的常规dll。如何将常规库转换为MFC扩展库

或是经过长时间的工作后,对这场灾难的任何解决方案

编辑


这是调用堆栈,其中没有导出的函数,它全部在应用程序中。从dll调用任何东西之前,都会出现错误

解决方案


当我将dll转换为MFC扩展库时,问题就解决了。实际上,我创建了一个新的MFC扩展dll,并欺骗了它的属性、dll主、stafx包含和预处理器定义

static AFX_EXTENSION_MODULE MFCExtensionDLL = { NULL, NULL };

extern "C" int APIENTRY DllMain( HINSTANCE hInst, DWORD fdwReason, LPVOID)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("MFCExtension.DLL Initializing!\n");

        // Extension DLL one-time initialization
        if (!AfxInitExtensionModule(MFCExtensionDLL, hInst))
            return 0;


        new CDynLinkLibrary(MFCExtensionDLL);

        //My initialization code

        return 1;
    }
    else if (fdwReason == DLL_PROCESS_DETACH)
    {
        // Terminate the library before destructors are called
        AfxTermExtensionModule(MFCExtensionDLL);
        // my finalization code
        return 1;
    }
}
属性

in the properties of project->configuration properties->general Use of MFC = Use MFC in a Shared DLL
,


在.dll中使用MFC时,必须确保.dll可以在.rc文件中找到字符串和位图之类的资源句柄。MFC为指向该.dll资源的每个.dll维护一个内部状态。当从应用程序(或另一个.dll)调用该.dll时,您必须“帮助”MFC获得正确的内部状态,否则它将无法找到您的资源并将断言

在您的示例中,我看不到调用堆栈中的函数正下方的函数,但是如果它是一个导出函数,那么MFC状态问题很可能就是正在发生的事情

确保已将
AFX\u MANAGE\u STATE
宏放在可从外部访问的任何函数(导出函数)的顶部。这将大大有助于解决你的问题


Microsoft参考:

如果您使用dll文件中的资源或窗口,可以尝试这种方法。此代码可以位于dll本身中。每当创建资源时,主进程的当前资源句柄将设置为dll的资源句柄并使用该句柄

在任何窗口创建或资源更改后,将其恢复为旧值

hdllresource = ::LoadLibrary(<dllfile containing the resource>);
hcurrentInst = AfxGetResourceHandle();
AfxSetResourceHandle(hdllresource );

//do your window creation or resource loading stuff 

AfxSetResourceHandle(hdllresource);
hdllresource=::LoadLibrary();
hcurrentInst=AfxGetResourceHandle();
AfxSetResourceHandle(hdllresource);
//做你的窗口创建或资源加载的事情
AfxSetResourceHandle(hdllresource);

在此过程中没有调用导出的方法,我添加了调用stackTry,将宏放在创建时的顶部非常感谢您的努力和帮助,我已通过将库转换为MFC扩展dll解决了此问题。
hdllresource = ::LoadLibrary(<dllfile containing the resource>);
hcurrentInst = AfxGetResourceHandle();
AfxSetResourceHandle(hdllresource );

//do your window creation or resource loading stuff 

AfxSetResourceHandle(hdllresource);