0

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

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

断言失败消息

我单击重试和中断以获取导致断言的行是那个

发生断言的代码

所以问题出在资源上。当我与库链接时,MFC 无法获得正确的资源模块。

我认为这是因为我使用了一个使用 MFC 并共享 MFC 对象的常规 dll,如果我必须使用 MFC 扩展库的话。如何将常规库转换为 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

,

in the properties of project->configuration properties->C/C++->Preprocessor->Preprocessor Definitions->add _AFXEXT , make sure to delete _USERDLL if it exists
4

2 回答 2

1

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

在您的示例中,我看不到调用堆栈中的函数正下方的函数,但如果它是导出函数,则可能是 MFC 状态问题。

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

微软参考: http: //msdn.microsoft.com/en-us/library/ba9d5yh5 (v=vs.80).aspx

于 2013-06-24T00:57:51.223 回答
0

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

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

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

//do your window creation or resource loading stuff 

AfxSetResourceHandle(hdllresource);
于 2018-11-29T13:11:44.283 回答