类没有在dll中实例化

zar*_*zar 7 c++ dll mfc visual-studio-2010

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

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

   return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

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

**更新**

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

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

Rog*_*and 6

您描述的是动态链接到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;
}
Run Code Online (Sandbox Code Playgroud)

我建议您创建这样一个项目,然后将现有代码移植到其中,然后您将从一开始就拥有所有正确的项目设置和结构.这比尝试将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.
//
Run Code Online (Sandbox Code Playgroud)

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

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

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

文档AfxLoadLibrary有更多详细信息.