C语言之静态链接库与动态链接库(2)

一、动态链接库(Dynamic Link Library) 
动态链接库可以理解为将源代码编译成目标代码后打成的库,该目标代码库可被其他进程在执行时动态调用。DLL 有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容
二、动态链接库 vs静态链接库
1.静态链接库与动态链接库都是共享代码的方式
2.静态链接库(.lib)是在程序编译链接时就进行链接的执行代码库,链接完成后lib 中的指令全部被包含在最终生成的 EXE 文件中;链接之后静态链接库不能改变,如需改变需重新链接
3.动态链接库(.dll)可在程序执行时动态进行调用和卸载
三、动态链接库的制作
1. 在VC++6.0中新建一个名称为dllTest的 Dynamic Link Library工程,并新建dll.h和dll.cpp两个文件,dll.h和dll.cpp的源代码如下:


dll.h源文件
/*dll.h文件:*/
int add(int x,int y);
int substract(int x , int y);

dll.cpp源文件
/*dll.cpp文件*/
#define  DLL_API _declspec(dllexport)
#include <iostream>
using namespace std;
DLL_API int add(int a,int b)   //实现两个整数相加
{
       return a+b;
}
DLL_API int subtract(int a,int b)   //实现两个整数相减
{
       return a-b;
}
2. 然后编译,生成解决方案,就会在 debug文件夹下生成 dllTest.dlldllTest.lib文件,至此,动态链接库就做好了
3.动态链接库的调用
新建一个 win32控制台程序,新建 dllcall.cpp。内容如下
/*dllcall.cpp文件*/
#include <iostream>
using namespace std ;
#pragma comment(lib, "dllTest.lib")
extern int add(int a,int b);
extern int subtract(int a,int b);
int main()
{
       cout << add(31,42) << endl ;
       cout << subtract(55, 33) << endl ;
       return 0 ;
}
然后把 dllTest.dlldllTest.lib 拷贝到与 dllcall.cpp并列的目录下。接着,编译,链接,执行,就会得到结果。
对于动态链接库,链接的时候需要 .lib文件,运行的时候需要 .dll文件
四、一些补充
1. 两个 lib文件

我们发现,无论是静态链接库还是动态链接库,最后都有lib文件,那么两者区别是什么呢?

其实,两个是完全不一样的东西。静态库对应的lib文件叫静态库,动态库对应的lib文件叫导入库。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

2. 对于静态链接库,我们在编译和链接的时候已经将所有的代码都导入进来,因此,当生成可执行文件以后,可执行文件包含所有的代码。因此,在可执行文件运行时就不再需要静态库了,而对于动态链接库,实际上,可执行文件不包含DLL中的内容,只是通过导入库(.lib)知道了相应的地址信息,因此,可执行文件在运行时动态得去加载DLL.

五、小结

1. 静态库

* 静态库是把程序运行时需要使用的函数编译在一个二进制文件中,扩展名为.lib。当程序link时把静态库中的二进制数据和程序其它数据放到一起。程序运行时不在需要lib和dll文件的支持。这样做的坏处是开发出来的程序占用磁盘空间较大。特别是windows系统中本来就有或很多程序运行都需要的函数完全没有必要每次开发程序时都要使用各自的静态库。

* 静态库为.lib文件形式存在

* 链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大

* 如果有多个(调用相同库函数的)进程在内存中间时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。

2. 动态库

* 动态库在开发时仅是把dll中的函数名和参数放到应用程序中,应用程序运行时根据函数名和参数调用dll中的函数来运行,这样操作系统中的应用程序可以同时使用同一个dll。可以有效地节省硬盘空间,当然这样做使得程序设计更有层次。也有利于软件工程师的分工和信息安全

* 动态库以.dl文件形式存在,且一般都有一个对应的引入库以.lib文件形式存在。纯资源dll不生成.lib引入库。

   >引入库和静态库的扩展名均为*.lib,但是引入库仅包含一些函数名和参数信息,没有函数体,是为调用动态库服务的,它和动态库的关系相当于.h文件和.cpp文件之间的关系;

* 动态库两种绑定方式

   >静态绑定(static blnding) 使用静态绑定的程序在一开始载入内存的时候,载入程序就会把程序所有调用到的动态代码的地址算出、确定下来。这种方式使程序刚运行时的初始化时间较长,不过一但完成动态装载,程序的运行速度就很快。

   >动态绑定(dynamic binding)   使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序才又去计算这部分代码的逻辑地址。所以,这种方式侄程序初始化时间较短,但运行期间的性能比不上静态绑定的程序。

* 使用动态库的两种方法(windows)

  >方法一: load-time dynamic linking 
在要调用dll的应用程序链接时,将dll的输入库文件(import library,.lib文件)包含进去。具体的做 法是在源文件开头加一句#include ,然后就可以在源文件中调用dlldemo.dll中的输出文件了。

  >方法二: run-time dynamic linking 
不必在链接时包含输入库文件,而是在源程序中使用LoadLibrary或LoadLibraryEx动态的载入dll。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值