在C/C++中经常需要用到静态链接库和动态链接库。为了了解什么是静态链接库和动态链接库,我们首先需要了解什么是库。由于经常有许多代码需要重复利用,库就是指创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接。而静态链接库是指目标的代码只能进行静态的链接,静态链接库的结构比动态链接库简单,只是将所有的目标代码一起放在可执行文件中。这样静态链接库有一个问题就是非常浪费内存,因为如果内存中的几个进程包含相同的链接库,则代表其实有几份相同的代码在内存中,这其实是没有必要的。而动态链接库就是解决这个问题,动态链接库的执行文件中并不包含链接的目标代码,而是当执行文件载入内存时才链接库。所以执行文件可以“动态”的载入链接库。
生成静态链接库:
在windows中如果使用visual studio创建静态链接库的步骤是:
首先新建一个win32的工程,然后下一步时选择静态库(可以预编译头也可以不预编译头),然后生成两个文件分别是.h文件和.cpp文件。.h文件对函数进行声明,.cpp对函数进行定义。然后生成解决方案既可以在debug文件中找到相应的lib文件,这个文件则是对应的静态链接库。
而当调用时,则需要将.h文件和相应的lib文件都拷到需要调用静态链接库的工程中(存放的位置和相应的源代码在同一个文件夹中),在新的工程中包含.h文件,并使用#pragma comment(lib,"xxx.lib")语句包含静态链接库。
举例说明:
在.h文件中的代码:
- #ifndef LIB_H
- #define LIB_H
- extern "C" int exp(int a,int b);
- #endif
在.cpp文件的代码:
- #include "static.h"
- int exp(int a,int b)
- {
- int flag = 1;
- int result = 1;
- if b < 0
- flag = -1;
- while (b)
- {
- resultresult = result * a;
- b--;
- }
- resultresult = result * flag;
- return result;
- }
新工程中的代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include "static.h"
- #pragma comment(lib,"static lib.lib")
- int main()
- {
- printf("%d\n",exp(2,6));
- system("pause");
- return 0;
- }
可以发现结果为64。
生成动态链接库:
在windows中如果使用visual studio创建动态链接库的步骤是:
首先新建一个win32的工程,然后下一步 时选择dll(可以预编译头也可以不预编译头),然后生成两个文件分别是.h文件和.cpp文件。.h文件对函数进行声明,.cpp对函数进行定义。然后 生成解决方案既可以在debug文件中找到相应的dll文件,这个文件则是对应的动态链接库。
而当调用时,则需要将.h文件和相应的dll文件都拷到需要调用静态链接库的工程中(存放的位置和相应的源代码在同一个文件夹中),在新的工程中包含.h文件,然后使用LoadLibrary函数和GetProcAddress函数使用动态链接库。
.h文件如下:
- #ifndef LIB_H
- #define LIB_H
- extern "C" __declspec(dllexport) int exp(int a,int b);
- #endif
__declspec(dllexport)代表生成一个动态链接库的导出函数。
.cpp文件与静态链接库完全一样。
新工程中的代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include<Windows.h>
- #include "static.h"
- int main()
- {
- HINSTANCE hDll=NULL;
- typedef int(*PEXP)(int a,int b);
- PEXP pSum;
- hDll = LoadLibrary(L"dll.dll");
- pExp = (PSUM)GetProcAddress(hDll,"exp");
- printf("%d\n",pExp(2,4));
- system("pause");
- FreeLibrary(hDll);
- return 0;
- }
生成的结果为16。首先LoadLibrary导入链接库,GetProcAddress函数获得相应的函数。
值得注意的是:如果你导入lib文件或dll文件时没有写路径,则生成的exe文件需要和lib与dll文件在同一个文件夹中!!!