DLL(Dynamic Link Libraries)全面剖析(2)
2006-04-08 11:40:12 来源:WEB开发网- Non-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 模块状态。
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 函数添加初始化代码和结束代码。
和规则 DLL 相比,有以下不同:
1、它没有从 CWinApp 派生的对象;
2、它必须有一个 DLLMain 函数;
3、DLLMain 调用 AfxInitExtensionModule 函数,必须检查该函数的返回值,如果返回0,DLLMmain 也返回 0;
4、如果它希望输出 CRuntimeClass 类型的对象或者资源,则需要提供一个初始化函数来创建一个 CDynLinkLibrary 对象。并且,有必要把初始化函数输出;
5、使用扩展 DLL 的 MFC 应用程序必须有一个从 CWinApp 派生的类,而且,一般在InitInstance 里调用扩展 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 应用程序的。在讲述状态管理时解释其原因。
- ››Dynamic Multipoint Vpn for IPv6 详解
- ››Linkedin iPhone 3.0应用体验
- ››Dynamic link library for Symbian
- ››DLL(Dynamic Link Libraries)专题
- ››DynamicLayout-VC 6.0对话框动态布局解决方案
- ››link 方法
- ››link-list java版
- ››Links and Anchors: Window 2
- ››DLL文件基本原理及修改方法和通过改DLL来美化系统...
- ››Link Server的语法
- ››DLL头文件的格式和应用
- ››DLL初学者指南(非MFC)
赞助商链接