类没有在dll中实例化

 圈闭仔笨仔 发布于 2023-02-04 15:57

我已经构建了一个MFC项目(可执行文件)作为dll或更准确我已经添加了导出函数就像一个DLL.我可以加载并执行导出的函数,但问题是当我加载模块时,主应用程序类CMyApp theApp不会被实例化.这意味着我无法使用theApp我真正想要的对象.我甚至修改了下面的函数,所以它匹配标准MFC dll的函数.

BOOL CMyApp::InitInstance()
{
   CWinApp::InitInstance();

   return TRUE;
}

LoadLibrary()用来加载exe/dll.注意,我不是从dll导出任何c ++类,只是几个标准的C风格函数.这些函数内部想要使用主应用程序对象,但它没有实例化(从不调用它的构造函数).我需要做什么才能正确实例化app类,就像在标准的mfc dll中一样?

**更新**

理想情况下,我想在exe本身中提供导出的函数,我已经完成了,但是当我使用LoadLibrary应用程序theApp类加载它时,不会实例化.我相信这是相同的行为,即使它是一个DLL.我的项目有很多依赖项,并创建一个新的DLL项目,添加所有文件和库太麻烦了.我真的想改变当前项目的项目设置,如果有的话,我可以加载正确实例化的应用程序类,就像常规的MFC dll一样.但问题是我需要改变哪些项目设置?

注意:我将使用实例化主对话框对象#define.基本上dll版本的InitInstance()函数可以像我上面发布的那样简单.

1 个回答
  • 您描述的是动态链接到MFC的常规DLL.从此链接文章中选择部分描述会为您提供特征的子集:

    动态链接到MFC的常规DLL具有以下要求:

    这些DLL使用_AFXDLL进行编译,就像动态链接到MFC DLL的可执行文件一样.但_USRDLL也被定义,就像静态链接到MFC的常规DLL一样.

    这种类型的DLL必须实例化CWinApp派生类.

    这种类型的DLL使用MFC提供的DllMain.将所有特定于DLL的初始化代码放在ExitInstance中的InitInstance成员函数和终止代码中,就像在普通的MFC应用程序中一样.

    如果你使用VS2010的New Project Wizatd并选择创建MFC DLL的选项,这是你得到的默认值,尽管你可以从向导选项中选择其他类型的DLL:

    巫师

    因此,创建一个常规的DLL.它将为您生成必要的样板代码,包括CWinApp派生类.例如:

    // CMFCLibrary1App
    
    BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp)
    END_MESSAGE_MAP()
    
    // CMFCLibrary1App construction
    
    CMFCLibrary1App::CMFCLibrary1App()
    {
        // TODO: add construction code here,
        // Place all significant initialization in InitInstance
    }
    
    // The one and only CMFCLibrary1App object
    
    CMFCLibrary1App theApp;
    
    // CMFCLibrary1App initialization
    
    BOOL CMFCLibrary1App::InitInstance()
    {
        CWinApp::InitInstance();
    
        return TRUE;
    }
    

    我建议您创建这样一个项目,然后将现有代码移植到其中,然后您将从一开始就拥有所有正确的项目设置和结构.这比尝试将exe项目转换为dll项目容易得多.

    请务必注意必须编写导出函数的方式的不同之处.如上面的链接所示:

    因为这种DLL使用MFC的动态链接库版本,所以必须将当前模块状态显式设置为DLL的状态.为此,请AFX_MANAGE_STATE在从DLL导出的每个函数的开头使用宏.

    因此,即使您只导出C风格的函数,如果它们包装使用MFC的对象,那么导出的函数和导出类的任何公共函数都必须使用上述技术,特别是对于多线程应用程序.

    New Project模板也有助于插入解释这一点的注释:

    //TODO: If this DLL is dynamically linked against the MFC DLLs,
    //      any functions exported from this DLL which call into
    //      MFC must have the AFX_MANAGE_STATE macro added at the
    //      very beginning of the function.
    //
    //      For example:
    //
    //      extern "C" BOOL PASCAL EXPORT ExportedFunction()
    //      {
    //          AFX_MANAGE_STATE(AfxGetStaticModuleState());
    //          // normal function body here
    //      }
    //
    //      It is very important that this macro appear in each
    //      function, prior to any calls into MFC.  This means that
    //      it must appear as the first statement within the 
    //      function, even before any object variable declarations
    //      as their constructors may generate calls into the MFC
    //      DLL.
    //
    //      Please see MFC Technical Notes 33 and 58 for additional
    //      details.
    //
    

    上述评论中提到的技术说明如下:

    TN033:MFC和的 DLL版本

    TN058:MFC模块状态实现

    看到你LoadLibrary用来动态加载你的DLL,如果你是从MFC应用程序这样做,你应该明智地使用AfxLoadLibrary(和相应的AfxFreeLibrary).正如MSDN所说:

    对于加载扩展DLL的MFC应用程序,我们建议您使用AfxLoadLibrary而不是LoadLibrary.在调用LoadLibrary之前,AfxLoadLibrary处理线程同步.AfxLoadLibrary的接口(函数原型)与LoadLibrary相同.

    该文档AfxLoadLibrary有更多详细信息.

    2023-02-04 15:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有