动态链接库

为什么会出现静态/动态库这种东西?

一些经常用到的代码,没必要每次写程序都拉过来重写一遍。把它们放到库中去,需要的时候只要包含库就可以了。

静态链接库 vs 动态链接库

静态链接库

有以下优点:

  • 解决代码的重用性
    但不能解决以下问题:
  • 编译时会吧库中的代码拷贝到应用程序里,应用程序偏大
  • 程序更新时,必须重新编译程序,不便于更新

动态链接库

动态链接库的出现很好地解决了静态链接库留下的所有问题。

(本文主要注重使用,so…)

静态链接库的使用

首先,你必须包含库文件 #pragma comment(lib, xxx.lib)
然后,就有以下两种方法:

  • 包含库提供的头文件
  • 在使用函数之前使用前置声明 extern void foo()

动态链接库的使用

动态库相对于静态库来说,程序运行到使用库代码的时候必须要存在,而静态库就不需要存在,它是完全拷贝的。

  • 隐式声明
    隐式声明,就是把整个库都隐式地加载进来,不过前提是必须有 .dll 对应的 .lib 文件
    使用方式跟静态链接库类似。
  • 显示声明
    显示声明就有一点点麻烦,不过有优点:
  • 只加载你需要的代码部分,而不是隐式地加载整个库,减小内存占用。
  • 只需要一个 .dll 文件就够了。
    在使用的时候,需要
//显示引入库,别忘了校验返回值,为 NULL 则失败
HMODULE hDll = ::LoadLibraryA("DLL_LOAD.dll");
//找到函数地址
typedef void (*pFun)(int iFoo);
//通过名字找到函数地址
pFun FunFoo = (pFun)::GetProcAddress(hDll, "Function");
if(NULL != FunFoo) {
//调用函数
printf("%d\n", (*FunFoo)(0));
}
//卸载库
::FreeLibrary(hDll);