微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 类没有在dll中实例化

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

   return TRUE;
}

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

**更新**

理想情况下,我想在exe本身中提供导出的函数,我已经完成了,但是当我使用LoadLibrary加载它时,应用程序将不会实例化该类.我相信这是相同的行为,即使它是一个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的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项目.

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

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的对象,那么导出的函数和导出类的任何公共函数都必须使用上述技术,特别是对于多线程应用程序.

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: DLL Version of MFC
> TN058: MFC Module State Implementation

看到您使用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有更多细节.

原文地址:https://www.jb51.cc/c/118099.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐