- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
一种是常规DLL静态链接到MFC,另一种是常规DLL动态链接到MFC。 前者使用MFC的静态链接库,生成的DLL文件长度大,一般不使用这种方式;后者使用MFC的动态链接库,生成的DLL文件长度小。 动态链接到MFC的规则DLL所有输出的函数应该以如下语句开始。 AFX_MANAGE_STATE(AfxGetStaticModuleState()) //此语句用来正确地切换MFC模块状态 最后一种是MFC扩展DLL,这种DLL特点是用来建立MFC的派生类,DLL只被用MFC类库所编写的应用程序所调用。 前面已经介绍过,Extension DLLs 和Regular DLLs不一样,它没有一个从CWinApp继承而来的类的对象,编译器默认了一个DLL入口函数DLLMain()作为对DLL的初始化,可以在此函数中实现初始化,代码如下。 BOOL WINAPI APIENTRY DLLMain(HINSTANCE hinstDll,DWORD reason,LPVOID flmpload) { switch(reason) { …//初始化代码 } return true; } 11.4.3 导出函数调用约定 关于动态链接库输出函数的约定有调用约定和名字修饰约定两种。 调用约定决定着函数参数传送时入栈和出栈的顺序,以及编译器用来识别函数名字的修饰约定。 名字修饰约定随调用约定和编译种类(C或C++)的不同而变化。 为了让不同的编程语言共享动态链接库带来的方便,函数输出时必须使用正确的调用约定,并且最好不带有任何由编译器生成的名字修饰。 下面详细介绍实现这些需求的方法。 1.调用约定 Visual C++ 6.0支持的函数调用约定有多种,在这里主要介绍_stdcall调用约定、C调用约定和_fastcall调用约定。 图11-3 编译环境设置 2.函数名修饰约定 函数名修饰约定随编译种类和调用约定的不同而不同,下面分别说明。 对于C编译,_stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为_functionname@number。 _cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_functionname。 _fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@functionname@number。 11.2.1 DllMain()函数 每一个DLL必须有一个入口点,这就像用C语言编写的应用程序一样,必须有一个WinMain函数一样。 在Non-MFC DLL中DllMain()是一个默认的入口函数,不需要编写自己的DLL入口函数,用这个默认的入口函数就能使动态链接库在被调用时初始化。 如果应用程序的DLL需要分配额外的内存或资源,即对每个进程或线程初始化和清除操作时,就需要在相应的DLL工程的CPP文件中对DllMain()函数按照下面的格式书写,代码如下。 11.2.2 DLL的导出函数 当C/C++编译器看到变量、函数原型或C++类之前的这个修改符的时候,它就将某些附加信息嵌入产生的.obj文件中。 当链接DLL的所有.obj文件时,链接程序将对这些信息进行分析。 当DLL被链接时,链接程序要查找关于输出变量、函数或C++类的信息,并自动生成一个.lib文件。 该.lib文件包含一个DLL输出的符号列表。 当然,如果要链接引用该DLL的输出符号的任何可执行模块,该.lib文件是必不可少的。 除了创建.lib文件外,链接程序还要将一个输出符号表嵌入产生的DLL文件。 这个输出节包含输出变量、函数和类符号的列表(按字母顺序排列)。
文档评论(0)