库分为静态库和动态库。静态库与可执行文件打包,动态库与可执行文件独立。静态库加载需要.lib和.h文件。动态库隐式加载需要.dll、.h、.lib文件,显示加载只需要.dll文件
静态库
在链接阶段库将会与目标汇编后的目标文件.o一起打包生成可执行文件。成为可执行文件的一部分,后续此库就可以消失了。也就是说在编译的最后一步(链接阶段),如果程序需要使用静态库,在这一步都会一起打包到可执行文件中
生成
// 头文件
#ifndef _MYLIB_H_
#define _MYLIB_H_
void fun(int a);
extern int k;
class testclass
{
public:
testclass();
void print();
};
#endif
// 定义
#include "stdafx.h"
#include "testlib.h"
#include <iostream>
using namespace std;
void fun(int a)
{
cout << "a: "+a << endl;
}
int k = 222;
void testclass::print()
{
cout << "k: " + k << endl;
}
testclass::testclass()
{
cout << "init" << endl;
}
加载
vs2010加载静态库需要 接口头文件、.lib库文件
#include "stdafx.h"
#include "testlib.h"
#include <iostream>
using namespace std;
// 也可使用项目附加库目录
#pragma comment(lib,"testlib.lib")
int _tmain(int argc, _TCHAR* argv[])
{
int a = 23;
cout << "a: "<< a << endl;
return 0;
}
动态库
动态库在编译阶段都不会有什么动作,只有在程序运行时才被加载,也就是动态库的链接是发生在程序运行时期的,它和可执行文件是分开的,只是可执行文件在运行的某个时期调用了它
生成
动态库生成两个有用文件,一个是.lib,一个是dll。这里的.lib本质上不同于静态库中的.lib。这里的.lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体实现。而静态库中的lib包含了索引和实现
vs2010中新建
新建项目=》win32项目=》dll 勾选空项目
https://jingyan.baidu.com/article/5bbb5a1bd4a7bd13eaa17968.html
// 头文件
// 动态库生成的时候需要在接口前加上__declspec(dllexport),而导入的时候需要加__declspec(dllimport)
#ifdef DLL_EXPORTS
#define DLL_API_XYG __declspec(dllexport)
#else
#define DLL_API_XYG __declspec(dllexport)
#endif
class DLL_API_XYG Cdll
{
public:
Cdll(void);
};
extern DLL_API_XYG int ndll;
extern "C" DLL_API_XYG int add(int x, int y);
// 定义
#include "stdafx.h"
#include "testdll.h"
DLL_API_XYG int ndll = 6;
DLL_API_XYG int add(int x, int y)
{
return x + y;
}
Cdll::Cdll(void)
{
}
加载
隐式加载
需要接口头文件,dll文件,lib文件
文件位置:.h和.lib加载方式与静态加载完全一致。但.dll文件必须放在环境变量指定的目录下。当然通常是与目标.exe文件放在一起
#include "stdafx.h"
#include "testdll.h"
// 也可使用项目附加库目录
#pragma comment(lib, "testdll.lib")
int _tmain(int argc, _TCHAR* argv[])
{
printf("%d
", add(22, 33));
getchar();
return 0;
}
显示加载
只需要dll
#include "stdafx.h"
// #include "testdll.h"
#include <Windows.h>
typedef int(*DLLDEMOFUNC)(int , int);
int _tmain(int argc, _TCHAR* argv[])
{
DLLDEMOFUNC dllFunc = nullptr;
HINSTANCE hDll;
// 动态加载dll
hDll = LoadLibrary(L"testdll.dll");
// 根据函数名获取dll地址
dllFunc = (DLLDEMOFUNC)GetProcAddress(hDll, "add");
printf("%d
", dllFunc(22, 23));
getchar();
// 卸载dll
FreeLibrary(hDll);
return 0;
}