Window创建并使用动态链接库

Windows下动态链接库(DLL)的创建与使用详解
本文详细介绍了如何在Windows环境下创建和使用动态链接库(DLL)。首先,解释了导出符号的概念,包括使用__declspec属性关键字和模块定义文件(.def)。接着,展示了创建DLL的具体步骤,包括两种不同的导出方式。最后,阐述了如何在应用程序中导入和使用DLL,强调了.lib文件的作用和链接过程。

1.关于导出符号

动态链接库给外部文件提供一些函数或变量,将这种提供函数或变量的行为称为导出符号。而外部文件使用这些函数或变量的行为则称为导入符号。在Linux 的ELF文件中,默认导出共享对象中的所有全局符号,而在 Windows 中的 DLL 中,则默认所有符号都不导出;因此,在 DLL 中需要显示的指定哪些符号是导出的符号,有以下两种方式指定一个符号是否导出:


1).__declspec 属性关键字

通过属性关键字 __declspec(dllexport) 来声明动态链接库文件中一个符号或函数是导出符号

通过属性关键字 __declspec(dllimport)来声明动态链接库文件中一个符号或函数是导入符号

2).模块定义文件 .def

模块定义文件用于控制链接过程,为链接器提供有关链接程序的导出符号,属性以及其他信息。定义方式下述


2.创建动态链接库

假设 DLL 库的源代码定义在 math.c 中,根据声明导出符号的方式不同,有以下两种对应的定义:

1)使用__declspec 属性关键字

/* math.c */
__declspec(dllexport)double add(double a,double b)
{
	return a+b;
}

__declspec(dllexport)double sub(double a,double b)
{
	return a - b;
}
编译方式如下:
cl /LDd math.c

其中 /LDd 指示声明 debug 版本的 DLL。/LD 指示声明 release 版本的DLL,不加任何参数默认生成 exe 可执行文件

2)使用模块定义文件:

使用模块定义文件,则在 math.c 的源文件中不需要指明函数的属性,即定义为普通定义:

/* math.c */
double add(double a,double b)
{
	return a+b;
}

double sub(double a,double b)
{
	return a - b;
}
定义对应的模块定义文件 math.def,如下:

LIBRARY math
EXPORTS
add
sub
该文件声明动态链接库中的导出符号有 add 与 sub。编译生成动态链接库的命令如下:

cl /LD /DEF math.def math.c


通过上述的命令后,将生成四个文件, math.dll,math.obj,math.exp,math.lib 这四个文件,其中 math.dll 即是我们需要的DLL文件,Math.obj 则是编译的目标文件


3.使用动态链接库

程序使用DLL 的过程其实是导入过程,对于从其他DLL 导入的符号,需要使用 __declspec(dllimport) 指令来显示的声明某个符号为导入符号。这与ELF 中的情况不同,ELF 中使用一个外部符号时,不用额外声明。

假设我们定义 main.c  的文件来使用 math.dll 中的 sub 函数,源代码如下:

/* main.c */
#include <stdio.h>

__declspec(dllimport) double sub(double,double);

int main()
{
	printf("%f\n",sub(3,2.1));
	return 0;
}


在编译时,通过如下指令来生成可执行文件:

cl /c main.c          //该命令指示编译器将 main.c 编译成目标文件 main.obj

link main.obj math.lib  //使用链接器将 main.obj 与math.lib 链接在一起产生一个可执行文件 main.exe

说明一下 math.lib ,“.lib”文件是一组目标文件的集合,其中并不真正包含 math.c 中的代码和数据,它是用来描述 math.dll 的导出符号,它包含了 main.o 链接 math.dll 时所需要的导入符号以及一部分 “桩”代码,又被称为“胶水”代码,以便将程序与DLL 粘合在一起。这种 .lib 文件又被称为导入库

linux 下的动态链接库的符号信息都包含在.so文件中,不需要再生成目标文件后再进行一次静态链接

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值