实验八 动态和静态链接库
一、实验目的
• 理解动态链接库和静态链接库的作用和不同;
• 掌握编写和生成动态链接库和静态链接库的方法;
• 掌握使用动态链接库和静态链接库的方法。
二、实验环境
PC(1台)、Microsoft Visual VC++ 6.0或其他编译平台。
三、实验参考
例1.实验七例1写了main.c,calc.h和calc.c,请新建一个静态链接库工程,将calc.c和calc.h生成静态链接库calc.lib;新建一个控制台工程,将calc.h和calc.lib拷贝到工程文件夹,在main.c中使用该链接库,实现max函数功能。
[源程序]
控制台测试工程
main.c
#include
#include”calc.h” //需要头文件中max函数的声明
#pragma comment(lib, “calc.lib”) //将静态链接库通过预编译命令包含进来
int main()
{
printf(“%d”,max(3,4));
return 0;
}
静态链接库工程
calc.h
#ifndef CALC_H
#define CALC_H
int max(int x, int y);
#endif
calc.c
#include”calc.h”
int max(int x, int y)
{
return x>y?x:y;
}
[程序输入]
无
[程序输出]
4
[程序分析]
静态链接库(lib)与动态链接库(dll)都是共享代码的方式,它们最主要的区别是:
采用静态链接库时,lib中的内容被全部直接包含在最终生成的exe文件中;但采用动态链接库时,该dll不必被包含在最终exe文件中,exe文件执行时可以“动态”地加载和卸载这个与exe独立的dll文件,从而在运行时节省系统资源。
静态链接库由.h和.lib文件组成,.h文件要声明.lib中供外界调用的函数的原型,不能缺少。
VC6中调用静态链接库.lib一共有3种方法:
1.使用语句#include “**.h”,并将**.h拷贝到当前工程目录下;对**.lib使用语句 #pragma comment(lib,”***\\**.lib”),将**.lib拷贝到目录”***\\”下。
2.使用语句#include “**.h”, 并在工具->选项->目录->路径中添加**.h的路径;对**.lib,在工程->设置->连接->对象/库模块中添加**.lib,并在工具->选项->目录->路径中添加**.lib的路径。
3. **.h文件的处理同1或2;对**.lib,在工程->添加到工程->文件中导入此.lib文件。
例2.实验七例1写了main.c,calc.h和calc.c,请新建一个动态链接库工程,将calc.c和calc.h生成动态链接库calc.dll和calc.lib;新建一个控制台工程,将calc.dll和calc.lib拷贝到工程文件夹,在main.c中使用该链接库,实现max函数功能。
[源程序]
控制台测试工程
main.c
#include
#pragma comment(lib, “calcDll.lib”) //加载dll导出的函数和符号名称
_declspec(dllimport) int max(int, int); //导入函数max
int main()
{
printf(“%d”,max(3,4));
return 0;
}
动态链接库工程
calc.h
#ifndef CALC_H
#define CALC_H
__declspec(dllexport) int max(int, int); //导出函数,声明
#endif
calc.c
#include”calc.h”
__declspec(dllexport) int max(int x, int y) //导出函数,定义
{
return x>y?x:y;
}{
return x>y?x:y;
}
[程序输入]
无
[程序输出]
4
[程序分析]
动态链接库dll独立于exe文件,在exe文件运行时才会加载。有两种加载方式:隐式加载和显示加载。
隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存。隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长。
显式加载又叫运行时加载,指主程序在运行过程中需要DLL中的函数时再加载,不需要时可卸载,提高软件打开速度和内存需求。
本例是隐式加载。需要用到lib和dll文件,.lib 文件包含DLL导出的函数和变量的符号名,只是用来为链接程序提供必要的信息;.dll 文件才包含实际的函数和数据。
VC6中调用动态链接库需要首先包含lib文件:
1.使用语句 #pragma comment(lib,”***\\**.lib”),将**.lib和**.dll拷贝到目录”***\\”下。
2.在工程->设置->连接->对象/库模块中添加**.lib,并在工具->选项->目录->路径中添加**.lib的路径。
然后,使用_declspec(dllimport) 声明dll中的函数。
显式加载需要用到
四、实验习题
• 在实验七的习题中大家编写了包含结构体定义和声明打印输出函数的student.h、定义打印输出函数的student.c文件、包含主函数的main.c,请仿照例题1,新建静态链接库工程,改写student.h和student.c,生成静态链接库student.lib;
• 新建控制台工程,改写main.c,使用student.h和student.lib,完成实验七的功能;
• 仿照例题2,新建动态链接库工程,改写student.h和student.c,生成动态链接库student.dll和student.lib;
• 新建控制台工程,改写main.c,使用student.dll和student.lib,完成实验七的功能。