c++ - 类未在 dll 中实例化

标签 c++ visual-studio-2010 dll mfc

我已经构建了一个 MFC 项目(可执行文件)作为 dll,或者更准确地说,我已经像 dll 一样向它添加了导出功能。我可以加载和执行导出的函数,但问题是当我加载模块时,主应用程序类 CMyApp theApp 没有被实例化。这意味着我不能使用我真正想要的 theApp 对象。我什至修改了下面的函数,使其与标准 MFC dll 的函数相匹配。

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

   return TRUE;
}

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

** 更新 **

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

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

最佳答案

你描述的是Regular DLL Dynamically Linked to MFC .从这篇链接文章中选择部分描述可以为您提供特征的子集:

A regular DLL, dynamically linked to MFC has the following requirements:

  • These DLLs are compiled with _AFXDLL defined, just like an executable that is dynamically linked to the MFC DLL. But _USRDLL is also defined, just like a regular DLL that is statically linked to MFC.

  • This type of DLL must instantiate a CWinApp-derived class.

  • This type of DLL uses the DllMain provided by MFC. Place all DLL-specific initialization code in the InitInstance member function and termination code in ExitInstance as in a normal MFC application.

如果您使用 VS2010 中的新建项目向导并选择创建 MFC DLL 的选项,这是您获得的默认设置,尽管您可以从向导选项中选择其他类型的 DLL:

wizard

因此,创建一个常规 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 项目。

请务必注意您必须编写导出函数的方式的差异。正如上面的链接所说:

Because this kind of DLL uses the dynamic-link library version of MFC, you must explicitly set the current module state to the one for the DLL. To do this, use the AFX_MANAGE_STATE macro at the beginning of every function exported from the DLL.

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

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.
//

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

鉴于您使用 LoadLibrary 来动态加载 DLL,如果您是从 MFC 应用程序执行此操作,则明智的做法是使用 AfxLoadLibrary(以及相应的AfxFreeLibrary)。正如 MSDN 所说:

For MFC applications that load extension DLLs, we recommend that you use AfxLoadLibrary instead of LoadLibrary. AfxLoadLibrary handles thread synchronization before you call LoadLibrary. The interface (function prototype) to AfxLoadLibrary is the same as LoadLibrary.

documentation for AfxLoadLibrary有更多详细信息。

关于c++ - 类未在 dll 中实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21051637/

相关文章:

c++ - 如何在 C++ 中使用 FMOD?

asp.net - 从虚拟机在主机上调试网站

c# - 在运行时从动态加载的 dll 创建对象列表

c++ - 无法使用 dyn.load windows 7 64bit 在 R 中加载 dll 文件

c++ - boost::bind 为具有默认值的成员函数?

c++ - 将 C++ 函数转换为 Delphi : what to do with void* parameter?

c++ - 将 vtkImageData 复制到 cv::Mat

asp.net - 自动附加到开发服务器的 Visual Studio 加载项

c++ - "/MD/MT "和 "dll lib"之间的概念歧义

c++ - 如何使用原子指针执行双缓冲?