引言
什么是库:库是写好的现有的,成熟的,可以复用的代码。
所谓静态、动态是指链接。将一个程序编译成可执行程序的步骤:
静态库在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
为什么还需要动态库?
空间浪费是静态库的一个问题。
1、另一个问题是静态库对程序的更新、部署带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。
2、动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行时才会载入,也解决了静态库对程序的更新、部署带来麻烦。用户只需要更新动态库即可,增量更新。
静态库
动态库
VS2012下新建静态库
第一步:新建一个静态库(static library)项目
第二步:编写项目内容
首先在头文件下添加一个头文件static.h
头文件static.h的内容如下:
int sum(int a, int b);//声明函数
在源文件下添加一个源文件static.cpp,内容如下:
#include "static.h"
#include "stdafx.h"
int sum(int x, int y){
return x + y;}
第三步:生成.lib文件
在菜单栏选择“生成”->“生成解决方案”就可以了。
然后打开工程文件夹,在Debug目录下(编译选择的是默认的Debug和Win32)就可以看到一个和项目名称相同的lib文件:
这样供给别人调用的lib文件就生成好了,下面讲如何调用这个静态库文件。
第四步:调用.lib文件
首先新建另外的项目TestCallLib1,这个项目将使用我们刚刚生成的静态库
将头文件static.h和静态库TestLib1.lib拷到TestCallLib1\TestCallLib1目录下
首先将主函数写好
#include <iostream>
#include "static.h"
using namespace std;
#pragma comment(lib,"TestLib.lib")
int main()
{
printf("%d\n",sum(1,2));
system("pause");
return 0;
}
(重点)
有两种方法调用静态库:
1、右键“目录”“属性”选择“链接器”->“输入”,在“附加依赖项”这里添加要调用的lib文件的名字:TestLib1.lib。
然后直接运行就搞定了
动态库的制作
动态库的制作
创建动态库关键是导出函数,DLL中导出函数的声明有两种方式:
一种方式是:在函数声明中加上__declspec(dllexport);
另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
1、采用模块定义(.def)文件声明
新建项目win32,应用程序类型选择dll
需要自己手动添加四个文件
头文件dllgenerator.h,内容
int Add(int, int);
int Mul(int, int);
函数定义文件dllgenerator.cpp,内容:
int Add(int a, int b)
{
return a + b;
}
int Mul(int c, int d)
{
return c * d;
}
dllmain.cpp : 定义 DLL 应用程序的入口点(这个固定)
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
需包含库<windows.h>,里面有很多与生成动态库的相关函数和参数
建立源文件Source.def(划重点)
在此文件第一行引号中填你的项目名称即可,EXPORTS下面列出要生成的函数名称 格式:“名称 @序号”)
LIBRARY "TestDll1"
EXPORTS
Add @1
Mul @2
2、通过关键字导出函数
新建项目过程同上!这里的关键是头文件中需要加入关键字__declspec(dllexport),这个关键字是导出函数的关键!
新建项目DLLTestor,将刚刚生成的.dll、.lib、.h文件拷贝到DLLTestor\DLLTestor文件下( .lib、.h 文件不是必须拷入的,我这里并没有拷入)
调用动态库是调用 .dll、 .lib、 .h 三个文件
编好代码并设置.lib和.h文件的调用路径
#include <iostream>
#include "static.h"
#include "dllgenerator.h"
using namespace std;
int main()
{
printf("%d\n",Add(1,2));
printf("%d\n",Mul(1,2));
system("pause");
return 0;
}
右键“目录”“属性”选择“链接器”->“输入”,在“附加依赖项”这里添加要调用的lib文件的名字:TestDll1.lib
运行得到结果