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版本可以像我上面发布的那样简单.
解决方法
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 theAFX_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.