静态库和动态库小结

Windows 的应用程序主要分为三类
1) 控制台程序 就是我们所说的 .exe文件
2) 窗口程序
3) 库程序
静态库程序 文件后缀为.lib 的文件
动态库程序 文件后缀名为.dll的文件

控制台程序和动态库程序都有入口函数,静态库程序没有入口函数。

静态库程序一直存在于硬盘上,不会进入到内存中,当程序运行时会被
链接到程序中。链接静态库程序时是将静态库程序中的代码嵌入到使用
程序中。
动态库程序有入口函数,会在程序运行时进入到内存中,但一旦进入
内存中,就会脱离原有程序,为其他程序所共享,当程序需要时进行
加载。链接动态库程序时,是将动态库中函数的地址给各个程序调用
动态库程序在内存中只有一份。

静态库程序的优点 :(目标文件运行)速度稍快,在运行时不需要库文件(独立性)
缺点 :占用空间大,不利于修改和维护。
动态库的优点: 占用空间小,修改和维护方便
缺点: 速度稍慢,在运行时需要库文件同时存在。

创建和使用库的步骤(VC++6.0):
1.创建和使用静态库
ps:创建前建议在当前目录下新建一个lib 文件夹用来存放静态库文件
1.1创建静态库程序
1) 新建工程,选择Win32 static library
2)新建一个文件(C/C++),编写静态库程序,buid 生成 .lib 文件

1.2使用静态库
1)新建一个工程,选择控制台应用文件 Win32 Console Application
2)新建一个文件 ,通过设置库文件路径,导入静态库文件,设置库文件路径
这里有两种方式
第一种方式 通过 #pragma comment(lib,”../lib/*.lib”)
第二种方式 在 project–setting 中选择 当前工程 然后点击link 将.lib文件所在
的路径放置到系统放置.lib文件的目录中
3)使用静态库函数
4)编译链接运行

注:如果在以C++编写的程序中调用用C语言编写的静态库,要在函数声名
前面加上 extern “C” 告诉编译器按照C的风格对程序进行编译,然后到对应
的静态库中查找函数,因为C++编译器会对函数进行换名,以至于会导致
在静态库中找不到相应的函数

2.创建和使用动态库程序
ps:创建前建议在当前目录下新建一个bin文件夹用来存放动态库文件
2.1 创建动态库程序
1)新建一个工程,选择 win32 dynamic library
2)新建一个文件(C/C++),编写动态库程序
注意:由于动态库程序会随着程序运行的时候一起进入内存,然后便与程序
独立分开,在程序链接动态库函数时导入。这样的话,首先便需要将动态库函数
导出,导出方式有两种,
第一种方式是在动态库函数名称前面加上导出声明即 “_declspec(dllexport)”
声明导出 是将动态库函数的偏移地址导出到lib文件中
第二种方式是在工程中新建一个 .def 文件即模块定义文件,文件编写格式如下:
LIBRARY 库名称
EXPORTS
库函数名称 + @1
库函数名称 + @2
库函数名称 + @3
……………………………….. //以此类推
模块定义文件导出 将函数的偏移地址导到了dll文件和lib 文件 各一份
3)点击build 生成后缀名为 .dll 的动态库文件
注:点击build 生成后缀名为.dll 的动态库文件的同时,也会生成一个后缀名为.lib
的文件,这个.lib 文件中存放的是动态库函数的偏移地址,当动态库程序
进入内存后,其他程序导入动态库函数时,就可以通过动态库程序首地址
加上 .lib文件中存放的函数偏移地址,获的动态库函数的绝对地址,从而便可以
使用动态库中的函数

2.2使用动态库
1) 新建一个工程,选择 控制台应用程序 Win32 Console Application
2)新建一个文件(C/C++),编写程序来链接使用动态库程序,程序链接
动态库也分为两种方式,一种是隐式链接,一种是显示链接
所谓隐式链接 就是由操作系统帮我们去查找动态库函数,从而使程序正确
运行
而显示链接 就是要由程序员手动去查找动态库函数,从而使程序正确运行

2.2.1 隐式链接动态库
1) 在函数的声明前加入导入声明 即”_declspec(dllimport)”
2)#pragma comment(lib,”bulid 生成的lib文件的相对路径”),这是为了
便于链接器 查找到动态库函数的偏移地址
3)上面两步完成之后,编译链接都没问题,然后运行会出错,会提示找不到
对应的 .dll文件,这时需要将.dll文件放置到一些指定的目录中,如:
当前工程所在的目录
可执行文件所在的目录
也可以放置在系统所在的目录 windows/system 或者 windows/system32

建议放置在与可执行文件中一个目录中,这样当更换操作系统或者给用户使用时
就无需更改动态库文件路径。

2.2.2 显示链接动态库
显示链接动态库需要用到一些函数,而且有一个前提 就是在声明导出动态库函数时
要采用模块定义文件进行声明
1) 采用typedef 定义函数指针类型 如 typedef int(*DLL_add)(int m,int n);

2) 拿到动态库程序实例句柄
HMODULE/等价于HINSTANCE/ LoadLibrary(“动态库文件名或全路径”)
当采用填写动态库文件名时要注意将 .exe 文件 与 .dll 文件放在同一个目录中

3) 得到动态库函数的绝对地址(偏移地址 + 动态库程序首地址)
FARPROC GetProcAddress(
HMODULE hModule, LPCSTR lpProcName)
第一个参数: 动态库程序实例句柄,用来拿到动态库程序首地址
第二个参数: 创建动态库时所写的函数名称,即代表动态库函数的偏移地址(相对地址)
返回值: 返回动态库函数的绝对地址
4) 使用动态库函数

5)卸载动态库函数,
BOOL FreeLibrary(HMODULE hModule);

2.2.3 两种链接方式的对比

1)在库函数的定义不变情况下:

隐式链接,由于库函数地址是在程序编译链接时设置,所以当动态库变化后,使用程序需要重新编译链接。

显式链接,由于库函数地址是在程序执行时,动态的从库中查询,所以库变化后,不需要重新编译链接。

2)动态库加载
隐式链接,动态库是在程序启动时就被加载,当DLL不存在,程序无法启动

显式链接,动态库只在使用LoadLibrary函数,才会被加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值