zoukankan      html  css  js  c++  java
  • C++ 静态库 与 动态库

    基础知识

    参考内容

    C++静态库与动态库的区别
    通俗理解动态库与静态库区别
    静态库与动态库的优缺点
    动态库和静态库的理解
    《程序员的自我修养——链接、装载与库》
    lib 和 dll 的区别、生成以及使用详解
    C++创建和使用动态链接库
    C++动态库封装及调用

    动态库 与 静态库

    静态库 在 unix系统中 是 .a 文件,在window系统是 .lib文件
    动态库 在 unix系统中 是 .so文件,在window系统是 .dll文件
    最本质的区别:该库是否被编译进目标程序内部
    他们之间的区别在于 程序编译的阶段,操作上不同。

    • 程序编译步骤:预编译 -> 编译 -> 汇编 -> 链接
    • 静态库和动态库就是在链接阶段行为不同

    静态库在链接阶段将会变生成的目标文件.o 和 引用到的库一起链接打包到可执行文件中。
    动态库只有在程序运行时 需要使用到库的时候,才加载库代码。

    静态库 动态库
    特点 静态库对函数库的链接是放在编译时期完成的 动态库把对一些库函数的链接载入推迟到程序运行的时期
    优点 1.程序在运行时与函数库再无瓜葛,移植方便
    2.编译成功的可执行文件可以独立运行,而不再需要向外部要求读取函数库的内容
    3.代码装载速度快,执行速度略比动态链接库快
    4.只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题
    1.将一些程序升级变得简单
    2.更加节省内存并减少页面交换
    3.可以实现进程之间的资源共享,共用库
    4.产品功能升级角度方便升级,只要替换对应动态库即可,不必重新编译整个可执行文件
    5.DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性
    6.不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数
    缺点 1.空间浪费,使用静态库的进程相当于复制一份静态库代码到程序中中,如果多个进程都使用,就会多复制几份
    2.更新问题:如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新
    1.使用动态链接库的应用程序不是自完备的,它依赖的DLL模块也要存在
    2.如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息
    3.速度比静态链接慢
    应用场景 从函数库集成的角度,若要将发布的所有子库(不止一个)集成为一个动态库向外提供接口,那么就需要将所有子库编译为静态库,这样所有子库就可以全部编译进目标动态库中,由最终的一个集成库向外提供功能。 适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试
    从产品化的角度,发布的算法库或功能库尽量使动态库,这样方便更新和升级,不必重新编译整个可执行文件,只需新版本动态库替换掉旧动态库即可

    静态库 创建 与 使用

    静态库 和 动态库的 创建使用 都是基于 window平台 ,VS实现的

    静态库 的 创建

    1. 创建空项目

    2. 编写所需要的头文件 和 cpp文件

    3. 可以在该项目 写个main.cpp 测试代码,后期生成库之前的时候注释掉

    4. 打开项目属性 -》 常规 -》配置类型选择静态库 -》确定

    5. 注释main函数,重新生成项目

    1. 找到对应的 h文件 和 lib文件 可以将其提取放到 其他地方

    静态库 的 使用

    在需要用到 该库的项目 设置一些配置 ,可以把 h文件 lib文件放到项目中一些对应位置

    • 方法一:配置项目属性
    1. 添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录。

    2. 添加文件引用的lib静态库路径:工程---属性---配置属性---链接器—常规—附加库目录:加上lib文件存放目录。

    3. 然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入—附加依赖项:加上lib文件名。

    4. 使用

    • 方法二:使用编译语句
      #pragma comment(lib,"./mylib.lib")
    • 方法三:添加工程中
      就像 添加.h和.cpp文件一样,把lib文件添加到工程文件列表中去.
      切换到"解决方案视图",--->选中要添加lib的工程-->点击右键-->"添加"-->"现有项"-->选择lib文件-->确定.

    动态库 创建 与 使用

    创建 和 配置信息 和静态库类似

    动态库 的 创建

    1. 建立一个空项目

    2. 建立需要的头文件 和 cpp文件

    3. 编写 头文件内容

    4. 编写cpp内容

    5. 在工程属性,C/C++ => 预处理器 => 预处理定义 中添加预定义宏 DLL_EXPORT

    6. 工程属性 -》常规 -》 配置类型 设置 动态库

    7. 生成项目(同理 如果有 main函数,则需要将其注释掉)

    动态库 的 使用

    1. 配置项目属性 (和静态库一致)

    A、添加工程的头文件目录:工程---属性---配置属性---c/c++---常规—附加包含目录:加上头文件存放目录。

    B、添加文件引用的lib静态库路径:工程---属性---配置属性—链接器—常规—附加库目录:加上lib文件存放目录。

    C 然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入—附加依赖项:加上lib文件名。

    1. 将 dll文件拷到 可执行文件的目录下
      否则运行时会出现这个错误:

    __declspec(dllexport) 与 __declspec(dllimport)

    声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类

    • __declspec(dllimport)

    声明一个导入函数,是说这个函数是从别的DLL导入。一般用于使用某个dll的exe中 不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量

  • 相关阅读:
    CSS 层叠样式表
    一. 图论
    二. log4j配置文件
    三.注解
    3. Map与Tuple
    MappedByteBuffer读写文件
    2. scala中的数组
    1.scala语法
    二. 模式匹配
    一.算法的数学基础
  • 原文地址:https://www.cnblogs.com/q1076452761/p/14637174.html
Copyright © 2011-2022 走看看