静态链接库和动态链接库

静态链接库和动态链接库


静态库

  • 静态库(.a、.lib)
  • 编译分预编译,编译,汇编,链接,静态库是在链接阶段,将汇编代码中引用的静态库一起打包到可执行文件中
  • 静态库也是一些.o文件的集合,所以才可以和汇编代码一起链接
  • 编译阶就链接到一块,程序运行时,静态库不再参与
  • 浪费空间,不同程序引用同一静态库,每个程序都需要链接到可执行文件里,拷贝一份
  • 如果静态库修改,用户程序需要全量的重新编译
  • 也就是静态库会在用户程序的源码里

静态库创建与使用

  • .cpp -> .o -> .a /.lib
  • linux下创建
1.编译
首先,将代码文件编译成目标文件.o(StaticMath.o)
g++ -c StaticMath.cpp
注意带参数-c,否则直接编译为可执行文件
2. 生成静态库.a文件
通过ar工具将目标文件打包成.a静态库文件
ar -crv libstaticmath.a StaticMath.o
生成静态库libstaticmath.a。 
大项目会使用makefile或cmake来生成静态库
  • linux下使用
1.代码中引用
#include "StaticMath.h"
2.编译时再指定
g++ TestStaticLibrary.cpp -L 静态库路径  -l 静态库名称,省略后缀
  • linux下创建
//命令行
1.编译
首先,通过使用带编译器选项 /c 的 Cl.exe 编译代码 (cl /c StaticMath.cpp),创建名为“StaticMath.obj”的目标文件。
2.生成静态库.lib文件
然后,使用库管理器 Lib.exe 链接代码 (lib StaticMath.obj),创建静态库StaticMath.lib。
//用vs编辑器生成静态库
3.使用静态库
用vs编辑器使用静态库

动态库

  • 动态库(.so、.dll)
  • 解决静态库的空间浪费
  • 动态库在用户程序运行时才链接、载入,不用在编译阶段链接(相当于复制)到户程序的源码里
  • 进程之间的资源共享:不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例
  • 动态库更新了,用户程序也不用重新编译

不同环境动态库编写的不同

在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数做出初始化的入口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。

l  Linux下gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要函数做特别的声明,编写比较方便

动态库创建与使用

  • .cpp -> .o -> .so
  • Linux下创建与使用
  • .so后缀
  • 用户程序实际装载动态库时,装在的是他的镜像,名字也是镜像的名字
  • 用户程序如何找到动态库,如果用户程序是elf格式可执行文件,里面有个LD_LIBRARY_PATH环境变量,写了路径,从这个路径里面找到库文件。如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中
1.生成目标文件 .o
-fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。
2.然后,生成动态库.so文件,此时要加链接器选项-shared
g++ -shared -o libdynmath.so DynamicMath.o
-shared指定生成动态链接库
3.其实上面两个步骤可以合并为一个命令:
g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp
4.使用
代码中引用
#include "../DynamicLibrary/DynamicMath.h"
然后编译时再加命令
g++ TestDynamicLibrary.cpp -L.动态库路径 动态库名称,不要后缀
  • windows 下
  • 动态库的.lib文件只是实际动态库的一个导入库,表示了动态库的地址,很小的文件
  • .dll
  • 要更麻烦一些
1.先写一个DllMain函数的入口文件,dllmain.cpp
#include "stdafx.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;
}
2.静态库文件的头文件里面,要有_declspec(dllexport)关键字
3.用vs编辑器生成静态库文件.o
4.使用静态库文件,在用户程序里引用静态库
5.用vs编辑器编译运行用户程序

动态库的显示调用

  • 上面介绍的动态库使用方法和静态库类似属于隐式调用,编译的时候指定相应的库和查找路径。其实,动态库还可以显式调用。【在C语言中】,显示调用一个动态库轻而易举
  • 有相应的函数
  • c++调用麻烦些
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值