(一)DLL和EXE的区别:
尽管 DLL 和应用程序都是可执行的程序模块,但它们之间有若干不同之处。
对于最终用户来说,最明显的差异在于 DLL 不是可直接执行的程序;
从系统角度讲,应用程序和 DLL 之间有两个基本差异:
-
应用程序可有多个同时在系统上运行的实例,而 DLL 只能有一个实例。
-
应用程序可以拥有堆栈、共用内存、文件句柄、消息队列这样的事物,而 DLL 不能。
(二)DLL的初始化
DLL 通常具有在 DLL 加载时必须执行的初始化代码(如分配内存)。使用 Visual C++ 时,在何处添加初始化 DLL 的代码取决于生成的 DLL 类型。如果不需要添加初始化代码或终止代码,则在生成 DLL 时没有什么特别的事情要做。如果需要初始化 DLL,则下表描述了应在何处添加代码。
DLL 类型 | 添加初始化代码和终止代码的位置 |
---|---|
规则 DLL |
在 DLL 的 CWinApp 对象的 InitInstance 和 ExitInstance 中。 |
扩展 DLL |
在“MFC DLL 向导”生成的 DllMain 函数中。 |
非 MFC DLL |
在您提供的称为 DllMain 的函数中。 |
在 Win32 中,所有 DLL 都可能包含一个可选的入口点函数(通常称为 DllMain),初始化和终止时都要调用此函数。这使您有机会在需要时分配或释放其他资源。Windows 在四种情况下调用入口点函数:进程附加、进程分离、线程附加和线程分离。
C 运行时库提供了一个名为 _DllMainCRTStartup 的入口点函数,并调用 DllMain。根据 DLL 类型的不同,应在源代码中包含一个名为 DllMain 的函数,或应用 MFC 库中提供的 DllMain。
(三)什么是 规则DLL ,扩展DLL ,非MFC DLL
what is non-MFC DLL ?
A non-MFC DLL is a DLL that does not use MFC internally, and the exported functions in the DLL can be called by either MFC or non-MFC executable files. Functions are usually exported from a non-MFC DLL using the standard C interface.
what is MFC-extension DLL?
An MFC extension DLL is a DLL that typically implements reusable classes derived from existing Microsoft Foundation Class Library classes. Extension DLLs are built using the dynamic-link library version of MFC (also known as the shared version of MFC).
What is reguar DLL?
A regular DLL statically linked to MFC is a DLL that uses MFC internally, and the exported functions in the DLL can be called by either MFC or non-MFC executables. As the name describes, this kind of DLL is built using the static link library version of MFC. Functions are usually exported from a regular DLL using the standard C interface.
MFC-extension dll 与 Regur Dll的主要区别是:前者可以导出MFC类,后者不能导出MFC类,只能导出自己编写的C++类。
1、Non-MFCDLL(非MFC动态库)
这种动态链接库指的是不用MFC的类库结构,直接用C语言写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用。如果建立的DLL不需要使用MFC,那么应该建立Non-MFCDLL,因为使用MFC会增大用户库的大小,从而浪费用户的磁盘和内存空间。
2、RegularDLL(常规DLL)
这种动态链接库和下述的ExtensionDll一样,是用MFC类库编写的,它的一个明显的特点是在源文件里有一个继承CWinApp的类(注意:此类DLL虽然从CWinApp派生,但没有消息循环),被导出的函数是C函数、C++类或者C++成员函数(注意不要把术语C++类与MFC的微软基础C++类相混淆),调用常规DLL的应用程序不必是MFC应用程序,只要是能调用类C函数的应用程序就可以,它们可以是在VisualC++、Delphi、VisualBasic、BorlandC等编译环境下利用DLL开发应用程序。常规DLL又可细分成静态链接到MFC和动态链接到MFC两种: (1)静态连接到MFC的动态连接库只被VC的专业般和企业版所支持。该类DLL里的输出函数可以被任意Win32程序使用,包括使用MFC的应用程序。输出函数有如下形式:
extern"C"EXPORTYourExportedFunction();
如果没有extern"C"修饰,输出函数仅仅能从C++代码中调用。
(2)动态链接到MFC的常规DLL里的输出函数可以被任意Win32程序使用,包括使用MFC的应用程序。所有从DLL输出的函数应该以如下语句开始:
AFX_MANAGE_STATE(AfxGetStaticModuleState())
此语句用来正确地切换MFC模块状态。
3、ExtensionDll(扩展DLL)
这种动态链接库是使用MFC的动态链接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。例如你已经创建了一个从MFC的CtoolBar类的派生类用于创建一个新的工具栏,为了导出这个类,你必须把它放到一个MFC扩展的DLL中。扩展DLL和常规DLL不一样,它没有一个从CWinApp继承而来的类的对象,所以,开发人员必须在DLL中的DllMain函数添加初始化代码和结束代码。与常规DLL相比,扩展的DLL有如下不同点: 1)它没有一个从CWinApp派生的对象;
2)它必须有一个DLLMain函数;
3)DLLMain调用AfxInitExtensionModule函数,必须检查该函数的返回值,如果返回0,DLLMmain也返回0; 4)如果它希望输出CRuntimeClass类型的对象或者资源(Resources),则需要提供一个初始化函数来创建一个CDynLinkLibrary对象。并且,有必要把初始化函数输出;
5)使用扩展DLL的MFC应用程序必须有一个从CWinApp派生的类,而且,一般在InitInstance里调用扩展DLL的初始化函数。
(四)no-MFC DLL 初始化:
为初始化非 MFC DLL,DLL 源代码必须包含一个名为 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; } |
注意 |
---|
DllEntryPoint 的 Platform SDK 文档指出,必须在链接器命令行上用 /ENTRY 选项指定入口点函数的实际名称。使用 Visual C++ 时,如果入口点函数的名称为 DllMain,则无需使用 /ENTRY 选项。实际上,如果使用了 /ENTRY 选项,但没有将入口点函数命名为 DllMain,则 C 运行时库将不会正确初始化。 |