MFC中的DLLNon-MFC DLL:指的是不用 MFC 的类库结构,直接用 C 语言写的 DLL,其输出的函数一般用的是标准 C 接口,并能被 非 MFC 或 MFC 编写的应用程序所调用。 Regular DLL:和下述的 Extension DLLs 一样,是用 MFC 类库编写的。明显的特点是在源文件里有一个继承 CWinApp 的类。其又可细分成静态连接到 MFC 和动态连接到 MFC 上的。 静态连接到 MFC 的动态连接库只被 VC 的专业 版和企业版所支持。该类 DLL 应用程序里头的输出函数可以被任意 Win32 程序使用,包括使用 MFC 的应用程序。输入函数有如下形式:extern "C" EXPORT YourExportedFunction();如果没有 extern "C" 修饰,输出函数仅仅能从 C++ 代码中调用。DLL 应用程序从 CWinApp 派生,但没有消息循环。
动态链接到 MFC 的 规则 DLL 应用程序里头的输出函数可以被任意 Win32 程序使用,包括使用 MFC 的应用程序。但是,所有从 DLL 输出的函数应该以如下语句开始:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
此语句用来正确地切换 MFC 模块状态。
(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)Regular DLL能够被所有支持 DLL 技术的语言所编写的应用程序所调用。在这种动态连接库中,它必须有一个从 CWinApp 继承下来的类,DLLMain 函数被 MFC 所提供,不用自己显式的写出来。
Extension DLL:用来实现从 MFC 所继承下来的类的重新利用,也就是说,用这种类型的动态连接库,可以用来输出一个从 MFC 所继承下来的类。它输出的函数仅可以被使用 MFC 且动态链接到 MFC 的应用程序使用。可以从 MFC 继承你所想要的、更适于你自己用的类,并把它提供给你的应用程序。你也可随意的给你的应用程序提供 MFC 或 MFC 继承类的对象指针。Extension DLL使用 MFC 的动态连接版本所创建的,并且它只被用 MFC 类库所编写的应用程序所调用。Extension DLLs 和 Regular DLLs 不一样,它没有从 CWinApp 继承而来的类的对象,所以,你必须为自己 DLLMain 函数添加初始化代码和结束代码。
(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)和规则 DLL 相比,有以下不同:
1、它没有从 CWinApp 派生的对象;2、它必须有一个 DLLMain 函数;3、DLLMain 调用 AfxInitExtensionModule 函数,必须检查该函数的返回值,如果返回0,DLLMmain 也返回 0;4、如果它希望输出 CRuntimeClass 类型的对象或者资源,则需要提供一个初始化函数来创建一个 CDynLinkLibrary 对象。并且,有必要把初始化函数输出;5、使用扩展 DLL 的 MFC 应用程序必须有一个从 CWinApp 派生的类,而且,一般在InitInstance 里调用扩展 DLL 的初始化函数。
DLL入口函数1、每一个 DLL 必须有一个入口点,DLLMain 是一个缺省的入口函数。DLLMain 负责初始化和结束工作,每当一个新的进程或者该进程的新的线程访问 DLL 时,或者访问 DLL 的每一个进程或者线程不再使用DLL或者结束时,都会调用 DLLMain。但是,使用 TerminateProcess 或 TerminateThread 结束进程或者线程,不会调用 DLLMain。
DLLMain的函数原型:
BOOL APIENTRY DLLMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: ....... case DLL_THREAD_ATTACH: ....... case DLL_THREAD_DETACH: ....... case DLL_PROCESS_DETACH: ....... return TRUE; } }
参数:
hMoudle:是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call:是一个说明动态库被调原因的标志。当进程或线程装入或卸载动态连接库的时候,操作系统调用入口函数,并说明动态连接库被调用的原因。它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用;DLL_THREAD_ATTACH: 线程被调用;DLL_PROCESS_DETACH: 进程被停止;DLL_THREAD_DETACH: 线程被停止;
lpReserved:是一个被系统所保留的参数;
2、_DLLMainCRTStartup
为了使用 "C" 运行库 (CRT,C Run time Library) 的 DLL 版本(多线程),一个 DLL 应用程序必须指定 _DLLMainCRTStartup 为入口函数,DLL 的初始化函数必须是 DLLMain。 _DLLMainCRTStartup 完成以下任务:当进程或线程捆绑(Attach) 到 DLL 时为 "C" 运行时的数据 (C Runtime Data) 分配空间和初始化并且构造全局 "C++"对象,当进程或者线程终止使用DLL(Detach) 时,清理 C Runtime Data 并且销毁全局 "C++" 对象。它还调用 DLLMain 和 RawDLLMain 函数。 RawDLLMain 在 DLL 应用程序动态链接到 MFC DLL 时被需要,但它是静态链接到 DLL 应用程序的。在讲述状态管理时解释其原因。