Lib作为“静态库”与“动态库”中的区别

0. 前言:

  

什么是静态连接库:

  静态库在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

为什么还需要动态库?

  • 空间浪费是静态库的一个问题。
  • 另一个问题是静态库对程序的更新、部署带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。
  • 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行时才会载入,也解决了静态库对程序的更新、部署带来麻烦。用户只需要更新动态库即可,增量更新

  LIB文件中存放的是函数调用的信息,值得一提的是Lib库有静态编译使用数据库和动态连接使用的数据库。

  

1. “静态库”和“动态库”的区别

  1. 静态库将导出声明和实现都放在lib中,编译后所有代码都嵌入到宿主程序, 链接器使用从静态链接库LIB获取所有被引用函数的声明与实现,最后链接生成放入exe文件。,并将库同代码一起放到可执行文件中。
  2. 动态库相当于一个h文件,是对实现部分(.dll文件)的导出部分的声明,编译后只是将导出声明部分编译到宿主程序中,运行时候需要相应的dll文件支持, 包含了函数所在的DLL文件和文件中函数位置的信息(入口),因此链接器使用从动态库的LIB获取所有被引用声明,最后链接生成放入exe文件exe运行时加载在当前目录中的DLL。因此这种方式称为动态链接库dynamic link library

  静态库:提供2分文件:

  (1).h 文件【包含lib中输出的类,以及函数原型】, 需要将该文件包含如“程序源文件”中

  (2).lib静态文件【包含对函数的声明与实现】  编译期间使用, 最终放入exe执行文件中,且最终的exe文件较大;

  因此:自己可以逐步把自己用gcc编译源文件生成的obj文件通过tlib命令加入到一个lib文件中,也可以把lib文件内的obj文件进行删除操作,还可以把内部的obj文件给提取出来。

  动态库:提供3分文件:

  (1).h文件【包含dll输出类型,以及函数原型】, 需要将文件包含入“程序源文件”中

  (2).lib静态导入文件【只包含对实现部分dll的导出声明】是编译器生成dll时自动生成的lib文件。

  (3).dll动态库【函数的实现部分】  “编译阶段”使用lib, 运行期间使用dll,因此如果要通过源码的编译,则需要lib库引入,如果要后续生成的执行文件运行起来,则需要dll放在exe的同目录下,最终的exe文件较小;

  即:

静态库的lib:即包括函数实现的声明索引信息,也有函数实现内容;  其实质是:多个obj文件的集合, obj文件是源码cpp文件“编译”后生成的obj。因此在编译静态库是根本不会出现“链接问题错误”;

动态库的lib:是在【编译-连接】生成dll后生成的文件。只包含函数实现的声明索引信息,不是obj文件的集合,只记录了dll文件中的函数的入库和地址信息,dll文件是函数的具体实现部分。

  如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载,显示使用dll。

  如果你查看dll动态链接库中的接口信息,可以通过vc自带的depends查看dll接口;

  dll是个编译好的程序,调用时可以直接调用其中的函数, 不参加工程的编译因此,将项目中扩展部分或者易发生变化的部分做成dll的形式,这样可以进行“动态”更新应用程序,而不需要替换exe的版本,只需要提供dll的动态替换或者添加即可。即实现“升级”的效果。

2. 静态库和动态库的使用

静态库使用方法:

(1)通过工程属性配置引入静态lib到工程“链接期间”的方式,因此配置连接器选项

  这种方法在项目的任何位置都可以使用lib工程,一定要注意,由于Debug,Release不同模式的库不一样(XXX.lib, XXXd.lib),因此要分别在两种不同模式下进行配置。

  1. 配置连接器使用到的XXX.lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录。对应本例中的lib文件夹(注意:里面存放的是.lib文件),一般都是通过VS中的工程变量名如:$(ProjectDir)作为相对路径引入,从而可以避免“全局路径”的困扰;
  2. 配置连接器引用上述路径中的lib文件名称:工程---属性---配置属性---链接器---输入---附加依赖项:加上lib文件名

变通:

  也可以采用:在“连接器”--输入--附加依赖项中:直接以相对路径+lib文件名尽心配置:“$(PrjojectDir/../Lib/XXX.lib”, 这样就省去了步骤1的配置。

(2)通过在代码cpp中直接编码的方式使用:

  这种方法优点是可以利用条件预编译指令也可以链接不同版本的LIB文件。在Debug方式下,产生的LIB文件是Debug版本,如Regd.lib;在Release方式下,产生的LIB文件是Release版本,如Regr.lib。

1. 加入预编译指令#pragma comment (lib,"*.lib").

 说明:一般是在使用地方的cpp文件中添加预编译执行加载。其中使用的是相对路劲该位置,即当前“项目中该文件”的目录作为“相对路径配置”的,一定要避免“绝对路径”的配置。

* 然后将lib拷贝到上述配置的目录位置,并将.h文件引入工程中即可。

动态连接库使用方法:

(1)隐式连接使用方法

  即通过“静态库lib”的引入方法, 再讲dll文件拷贝到exe相同的目录即可。完成隐式使用

3. 静态库的制作

  实质是对函数或者类的封装,只需要在导出的时候设置生成静态库类型即可.

(1)C++文件的静态库生成

   TestLib.h.h 文件,

#pragma once
void HelloWorld();

TestLib.cpp文件

#include <stdio.h>
#include "TestLib.h"
void HelloWorld()
{
printf("Hello World\n");
}

(2)C文件的静态库生成

 .h 文件, .c文件

  注意:一定要在.h文件中添加, extern c 的声明,这样可以防止C++编译器对C函数进行C++函数处理,从而导致生成lib失败,如下图;因为C++编译器对C函数会进行函数名称标识的修改,这样就不能够用.h文件中的函数声明进行c函数的直接调用了,即显示:不能解析Helloword@@YAXXZ 函数符号的调用。

  为了在C++代码中调用用C写成的库文件,就需要用extern"C"来告诉C++编译器:这是一个用C写成的库文件,请用C的方式来链接它们。

修改后的代码如下:

#pragma once

#ifndef __cplusplus
extern"C" { void HelloWorld();
#endif #ifndef __cplusplus
}
#endif

4. 动态库的制作

  参考博客:http://www.cnblogs.com/icmzn/p/7553716.html

  参考博客:https://www.cnblogs.com/zqh20145320/p/6772985.html

endl;

Lib作为“静态库”与“动态库”中的区别的更多相关文章

  1. Makefile中静态库,动态库的创建和使用以及解压缩命令

    应用层通过操作文件操控硬件 使用制作好的工具链: 刚开始学习时,用一些已经制作好的工具链,使用以下命令解压到gcc-3.4.5-glibc-2.3.6目录 cd /work/tools tar xjf ...

  2. VS中Debug和Realease、及静态库和动态库的区别整理(转)

    原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...

  3. VS中Debug和Realease、及静态库和动态库的区别整理

    一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...

  4. C语言中静态库和动态库笔记

    库 库,故名思议,是存放东西的地方,其中存放的东西可以被多个人公用. 程序中借用库的概念,描述将代码进行抽取,这种代码被大多数程序使用, 其过程具有一定的模块化.封装.抽象的特征. 按照库的使用方式, ...

  5. (转)HelloWorld CMake CMake中构建静态库与动态库及其使用

    继续完善Hello World,建立它的共享库, 包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc 向终端输出Hello ...

  6. 关于lib,dll,.a,.so,静态库和动态库的解释说明

    [转]关于lib,dll,.a,.so,静态库和动态库的解释说明 目录 1 什么叫程序库 2 什么是lib,什么是dll,什么是.a,什么是so,什么是静态库,什么是动态库 3 补充说明 4 作者 什 ...

  7. 在Linux中创建静态库和动态库

    我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库. 动态库在程序编译时并不会被连接到目标代码中 ...

  8. linux中C的静态库和动态库分析

    从开始学C语言写第一个"hello world"历程到现在,我依然困惑于到底这个程序完整的执行流程是什么样的.不过,现在我正在尝试一点一点的揭开它的面纱.现在,我尝试分析linux ...

  9. linux中创建静态库和动态库

    1. 函数库有两种:静态库和动态库. 静态库在程序编译的时候会被连接到目标代码中,程序运行时将不再需要改静态库. 动态库中程序编译的时候并不会连接到目标代码中,而是在程序运行时才被载入,因此在程序运行 ...

随机推荐

  1. C# 解决SharpSvn启动窗口报错 Unable to connect to a repository at URL 'svn://....'

    在远程机打开sharpsvn客户端测试,结果报错 Svn启动窗口报错 Unable to connect to a repository at URL 'svn://...' 咋整,我在win10我的 ...

  2. Android开发之SharedPreferences的封装

    对于大部分初学者来说,如果想利用SharedPreferences进行数据存储的话大部分人(包括本人)应该会这样: 存储: SharedPreferences sharedPreferences = ...

  3. 探索未知种族之osg类生物---器官初始化四

    上一节我们对完成了对osg生物内部非常重要器官graphicsContext的初始化工作.这样就可保证我们场景中至少有一个graphicContext存在,不至于刚出生就面临夭折.我们根据上一节中os ...

  4. python 计时程序运行时间

    import time time_start=time.time() time_end=time.time() print('totally cost',time_end-time_start)

  5. Python 反射机制

    Python的反射机制 Python的反射机制,就是反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块寻找指定函数,并执行.利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员 ...

  6. 设计师别浪费时间啦,快来试试这款Sketch标注插件吧

    随着移动互联网的快速发展,用户的需求也在不断地增大,这对产品经理还有设计师的考验是越来越大.市场环境的变化让我们深信为快不破,但是一个产品的产出需要各个环节的紧密配合,但往往在产品输出过程中,由于分工 ...

  7. 阿里云安骑士-Centos7系统基线合规检测-修复记录

    执行命令 sysctl -w net.ipv4.conf.all.send_redirects=0sysctl -w net.ipv4.conf.default.send_redirects=0sys ...

  8. 弹出DIV锁定代码

    <html>  <head>  <meta http-equiv="Content-Type" content="text/html; ch ...

  9. 【NIFI】 Apache NiFI 之 ExecuteScript处理(一)

    本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript FlowFile I / O简介 NiFi中的流文件由两个主要组件构成,即属性和内容.属性是关于内容/流文件 ...

  10. 【Web】前端裁剪图片,并上传到服务器(Jcrop+canvas)

    web网站中常常有的功能:上传头像.上传封面等:一般图片都有一定的比例限制,所以需要前端在上传图片时,进行裁剪,并把裁剪后的图片进行上传. 本例采用Jcrop插件实现裁剪效果,canvas裁剪图片,并 ...