DLL 动态链接库 基础知识

动态链接库的应用基础

A, 调用约定,调用约定(Calling convention)决定:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。编程调用DLL时,要注意调用约定的一致。

调用约定包括:

__cdecl

MFC默认调用约定。按从右至左的顺序压参数入栈,有调用者把参数弹出栈。对于C函数,__cdecl方式的名字修饰约定是在函数名称前添加一个下划线,对于C++函数使用不同的名字修饰方式。

__stdcall

所有的Win32 API函数都遵循该约定。按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于C函数,__stdcall的名称修饰方式是在函数名字前添加下划线,在函数名字后添加@和函数参数的大小。

__fastcall

头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈。编译器使用两个@修饰函数名字,后跟十进制数表示的函数参数列表大小。

thiscall

仅仅应用与C++成员函数。This指针存放于CX寄存器,参数从右到左压栈。Thiscall不是C++的关键字,不能使用thiscall声明函数,它只能由编译器使用。

naked call

采用上述调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。Naked call不产生这样的代码。Naked call不是类型修饰符,因此必须和__declspec共同使用。

Windows编程中常见的集中函数类型声明宏都与__stdcall和__cdecl有关:

#define CALLBACK __stdcall

#define WINAPI __stdcall

#define WINAPIV __cdecl

#define APIENTRY WINAPI

#define APIPRIVATE __stdcall

#define PASCAL __stdcall

对于C++编译器的函数名修饰规则:不管__cdecl, __fastcall还是__stdcall调用方式,函数修饰名都是以”?”开始,后面是函数在名字,再后面是参数表的开始标示和按照参数类型代号拼出的参数表。对于__stdcall方式,参数表的开始标示是”@@YG”,对于__cdecl方式则是”@@YA”,对于__fastcall方式则是”@@YI”.

参数表的拼写代号

拼写代号

含义

拼写代号

含义

X

void

D

Char

E

Unsigned char

F

Short

H

Int

I

Unsigned int

J

Long

K

Unsigned long (DWORD)

M

Float

N

Double

_N

Bool

U

Struct

PA

指针(后面的代号表明指针类型)

PB

Const类型指针(后面的代号表明指针类型)

函数的返回值不作特殊处理。参数表后以”@Z”标示整个名字的结束,如果该函数无参数,则以”Z”标识结束。

B, 导出和导入函数

DLL内的函数分为两种:

DLL导出函数,可供应用程序调用

DLL内部函数,只能在DLL内部使用,应用程序无法调用它们。

对于导出函数,DLL文件包含一个导出函数表,它包含了DLL中函数的符号名,标识符和实际的地址,这些信息可以使用Depends工具查到。当应用程序加载DLL时动态建立一个函数调用与函数地址的对应表,所以应用程序并不需要知道要调用函数的实际地址,可以通过函数的符号名和标识号来调用函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值