VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 181|回复: 1

VC++动态库编程-[2]入口点函数及其导出函数的讲解

[复制链接]
Syc 发表于 7 天前 | 显示全部楼层 |阅读模式
1、动态库导出函数的查看:
使用Vc++自带的Depends工具进行查看,但是只能看到函数的名字,具体的函数参数及返回值看不到,所以要把动态库导出函数声明的头文件(.h文件)打包给<<开发者>> 。

2、新建DLL工程:
大家在新建工程向导过程中,不要选择 “使用MFC” 选项,如果选上的话,会把DLL变为MFC规则DLL,就是我们上节课讲的第二种动态链接库。

3、DLL程序入口点函数:
CUI控制台程序(不是DOS):main
GUI用户界面程序:WinMain
DLL程序入口点函数:DllMain,注意:大小写是区别的(仅导出资源的DLL可以没有DllMain函数)。为大家讲解下具体的参数的应用。
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
    return TRUE;
}

①hModule参数:指向DLL本身的实例句柄;

②ul_reason_for_call参数:指明了DLL被调用的原因,可以有以下4个取值:
■DLL_PROCESS_ATTACH:
当DLL被进程 <<第一次>> 调用时,导致DllMain函数被调用,同时ul_reason_for_call的值为DLL_PROCESS_ATTACH,如果同一个进程后来再次调用此DLL时,操作系统只会增加DLL的使用次数,不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。
■DLL_PROCESS_DETACH:
当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的ul_reason_for_call值是DLL_PROCESS_DETACH。
★如果进程的终结是因为调用了TerminateProcess,系统就不会用DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程结束前没有机会执行任何清理工作。
■DLL_THREAD_ATTACH:
当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。 新创建的线程负责执行这次的DLL的DllMain函数,只有当所有的DLL都处理完这一通知后,系统才允许线程开始执行它的线程函数。
■DLL_THREAD_DETACH:
如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。
★注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。

/*********************************************************************/
还是请大家多多注意我★号的2个地方,此外ul_reason_for_call参数多采用 switch-case 结构类型。
/*********************************************************************/

③lpReserved参数:保留,目前没什么意义。

4、DLL导出函数:
DLL只有将函数进行导出,这样其他的程序才可以进行调用。
DLL里面可以有2种函数:一种是导出函数,供被DLL调用的程序使用,比如说是EXE等;另外一种是供DLL内部调用使用,不提供导出。

5、DLL导出函数的方式:*.def 文件或 __declspec(dllexport) 关键字:

①*.def 文件必须至少包含下列模块定义语句:

■文件中的第一个语句必须是 LIBRARY 语句。此语句将 .def 文件标识为属于 DLL。LIBRARY 语句的后面是 DLL 的名称。链接器将此名称放到 DLL 的导入库中。

■EXPORTS 语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 到 N,其中 N 是 DLL 导出函数的个数。

■注释语句,在语句前面加分号 “;” 。

例如:
;DLLTest.def : Declares the module parameters for the DLL.
LIBRARY   "DLLTest"
EXPORTS
   add   @1
   fun   @2

②_declspec(dllexport) 导出方式:
为了防止名字改编,将 extern "C" _declspec(dllexport) 语句放在想要导出函数的声明前面;
例如:
extern "C" _declspec(dllexport) int add(int a, int b);

注:如果要进行函数的导入则把dllexport换成dllimport即可,如:extern "C" _declspec(dllimport) 关于函数的导入方面,之后会为大家进行纤细介绍。


备注◆:大家在做外函数的导出工作之后,可以利用Depends工具查看一下所生成的DLL,看看导出函数是否成功。

备注◆:DLL导出函数是DLL最为常用的一种导出类型,关于DLL进行导出变量或DLL导出类,还有DLL进行导出资源的相关问题,大家可以网上找找相关的资料,这里就不讲解了,总体上来说与导出函数的方式都是大同小异的,大家要灵活运用。

本套教程由VC驿站原创,完全免费!
相关课程演示细节还请观看视频教程!
教程下载地址:http://www.cctry.com/thread-7-1-1.html

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

besteast 发表于 前天 18:40 | 显示全部楼层
不错的,谢谢分享

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站

本版积分规则

 
 
在线客服
工作时间:
8:00-18:00
客服热线:
13591366679
官方微信扫一扫

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )

返回顶部
x

VC驿站微信公众号cctry2009

GMT+8, 2018-1-16 23:01

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表