静态库

程序编译一般需经预处理、编译、汇编和链接几个步骤。在应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。

动态库

动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。DLL 是一个包含可由多个程序同时使用的代码和数据的库。Windows下动态库为.dll后缀,在linux在为.so后缀。

俩者区别

静态库是编写的时候加载进源代码进行编译的,如各种头文件。动态库是在程序运行的时候映射进程序的内存空间进行动态加载的,如DLL文件。静态库和动态库是两种共享程序代码的方式,它们的区别是:静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。

静态链接库生成方法

1、新建一个项目,选择Win32项目

2、选择静态库,预编译头可以加也可以不加,这里我不加

如果没有选静态库,可以在项目/工程属性/配置属性/常规/项目默认值配置类型中修改

3、添加.cpp文件和.h文件

(1)demo.cpp文件

#include<iostream>
#include<vector>
#include"BinarySearchLib.h"
using namespace std;//递归方法
int Binary_Search_Recursion(vector<int> v, int begin, int end, int key)
{if (begin > end)return -1;int mid = (begin + end) >> 1;if (v[mid] > key)return Binary_Search_Recursion(v, begin, mid - 1, key);else if (v[mid] < key)return Binary_Search_Recursion(v, mid + 1, end, key);elsereturn mid;
}//非递归方法
int Binary_Search(vector<int> v, int begin, int end, int key)
{if (begin > end)return -1;int mid = 0;while (begin <= end){mid = (begin + end) >> 1;if (v[mid] > key)end = mid - 1;else if (v[mid] < key)begin = mid + 1;elsereturn mid;}return -1;
}

(2)BinarySearchLib.h文件

#ifndef  _BinarySearchLib_H
#define  _BinarySearchLib_H#include<vector>
using namespace std;int Binary_Search_Recursion(vector<int> v, int begin, int end, int key);
int Binary_Search(vector<int> v, int begin, int end, int key);#endif

4、生成解决方案

这时候可以看到下方显示成功

5、把项目所在文件夹Debug文件夹下找到.lib文件

在这里我新建了一个控制台程序

(1)复制.lib和.h文件到需要使用项目的文件夹下

(2)把.h文件添加到工程中,并在工程中添加库#pragma comment(lib,"BinarySearchLib.lib")

如果不写#pragma comment(lib,"BinarySearchLib.lib")可以在项目/工程属性/链接器/输入/附加依赖项中添加BinarySearchLib.lib。

动态链接库生成方法

1、新建一个项目,选择Win32项目

2、选择DLL

如果没有选DLL,可以在项目/工程属性/配置属性/常规/项目默认值配置类型中修改

3、添加BinarySearchDll.h文件和BinarySearch.cpp文件

代码如下:(在静态库我用的是vector,但是显示调用的时候,得到的函数地址一直是0,不清楚原因,待究)

BinarySearchDll.h

#ifndef _MYCODE_H_
#define _MYCODE_H_#ifdef DLLDEMO1_EXPORTS
#define EXPORTS_DEMO _declspec( dllexport )
#else
#define EXPORTS_DEMO _declspec(dllimport)
#endifextern  "C" EXPORTS_DEMO int Binary_Search(int v[], int begin, int end, int key);#endif

BinarySearchDll.cpp

#include "stdafx.h"
#include "MyCode.h"int Binary_Search(int v[], int begin, int end, int key)
{if (begin > end)return -1;int mid = 0;while (begin <= end){mid = (begin + end) >> 1;if (v[mid] > key)end = mid - 1;else if (v[mid] < key)begin = mid + 1;elsereturn mid;}return -1;
}

4、生成->生成解决方案

Debug目录下有BinarySearch.lib文件和BinarySearch.dll文件

5、调用动态链接库

有两种调用方式,静态(隐式)调用和动态(显式调用)

(1)静态(隐式)调用,和静态链接库方式一样

把.h文件和.lib文件放在需要调用的项目目录下,把.h文件添加到工程中,并在工程中添加库#pragma comment(lib,"BinarySearchLib.lib")如果不写可以在项目/工程属性/链接器/输入/附加依赖项中添加BinarySearchLib.lib。并把生成的.dll.要放到,使用该库的工程的 debug()目录下。

(2)动态(显式)调用

显式调用只需把dll文件放在被调用的项目Debug目录下

需要包含windows.h,动态调用法要用Windows API中的LoadLibrary()和GetProcAddress()来调入dll库,指出库中函数位置。

代码如下:

#include <windows.h>
#include <iostream>
using namespace std;typedef int(*AddFunc)(int[], int, int, int);int main(int argc, char *argv[])
{int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };HMODULE hDll = LoadLibrary("DLLDemo1.dll");if (hDll != NULL){AddFunc add = (AddFunc)GetProcAddress(hDll, "Binary_Search");if (add != NULL){cout << add(data, 0, 7, 3) << endl;}FreeLibrary(hDll);}
}

可能会遇到的问题

1、上面已经说明,用vector不能调用,为什么?我还没解决

2、error C2664: “HMODULE LoadLibraryW(LPCWSTR)”: 无法将参数 1 从“const char [13]”转换为“LPCWSTR”

解决办法:项目->项目属性->配置属性->常规->字符集:选择使用多字节字符集

理论

(基本摘抄自博客)

1、.h .lib .dll文件关系

摘自:http://www.cnblogs.com/zcshan/archive/2010/12/03/1895605.html

.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。

附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件。如果要完成源代码的编译和链接,有头文件和lib就够了。如果也使动态连接的程序运行起来,有dll就够了。在开发和调试阶段,当然最好都有。

.h .lib .dll三者的关系是:

H文件作用是:声明函数接口

DLL文件作用是: 函数可执行代码

当我们在自己的程序中引用了一个H文件里的函数,编链器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用: 告诉链接器 调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,这也就是为什么需要附加依赖项 .LIB文件,它起到桥梁的作用。如果生成静态库文件,则没有DLL ,只有lib,这时函数可执行代码部分也在lib文件中

目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。在动态库的情况下,有两个文件,而一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

2、C++静态链接库与动态链接库

摘自:http://www.cnblogs.com/skynet/p/3372855.html

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。

所谓静态、动态是指链接。回顾一下,将一个程序编译成可执行程序的步骤:

图:编译过程

(1)静态库

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

试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

静态库对函数库的链接是放在编译时期完成的。

程序在运行时与函数库再无瓜葛,移植方便。

浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

(2)动态库

通过上面的介绍发现静态库,容易使用和理解,也达到了代码复用的目的,那为什么还需要动态库呢?
为什么还需要动态库?
为什么需要动态库,其实也是静态库的特点导致。
1)空间浪费是静态库的一个问题。

2)另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新

动态库特点总结:

1)动态库把对一些库函数的链接载入推迟到程序运行的时期。

2)可以实现进程之间的资源共享。(因此动态库也称为共享库)

3)将一些程序升级变得简单。

4)甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。

Window与Linux执行文件格式不同,在创建动态库的时候有一些差异。

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

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

与创建静态库不同的是,不需要打包工具(ar、lib.exe),直接使用编译器即可创建动态库。

其他文章:在自己的项目中调用别人的库的方法(static lib库,dynamic lib库以及dll动态库)_邓无邪的博客-CSDN博客

库文件、静态库(lib)与动态库(dll)的生成与使用相关推荐

  1. 【Android 逆向】arm 汇编 ( 使用 IDA 解析 arm 架构的动态库文件 | 使用 IDA 打开 arm 动态库文件 | 切换 IDA 中汇编代码显示样式 )

    文章目录 一.使用 IDA 打开 arm 动态库文件 二.切换 IDA 中汇编代码显示样式 一.使用 IDA 打开 arm 动态库文件 分析 Android SDK 中的 arm 架构的动态库 , 动 ...

  2. qt生成无ui界面动态库,有ui界面的动态库,以及含有资源文件和qss文件的动态库

    提要 此文分别就qt生成纯代码的动态库,含有ui文件的动态库以及含有资源文件qss文件和切图的动态库. 实现 1.纯代码的生成qt库.即没有ui文件的项目. 打开QtCreate,新建文件,选择lib ...

  3. Linux-动态链接与静态链接对比(动态库和静态库)

    博客转载自:Linux-动态链接与静态链接对比 一.库的基础概念: 在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于wi ...

  4. 【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )

    文章目录 I . CMake 引入动态库与静态库区别 II . Android Studio 中 CMake 引入动态库流程 III . 指定动态库查找路径 IV . 链接函数库 V . 完整代码示例 ...

  5. python第三方库文件传输_慢步学习,python库文件概述,再来点第三方库文件安装的干货...

    python是一个开源项目 我们知道Python一个开源的程序设计语言.但确切的说法应该是,Python是一个开源的编程项目,而这个项目由全球开发者共同开发. 就像数学一样,全球开源,有共同的规则,有 ...

  6. MFC的静态库.lib、动态库.dll(包含引入库.lib)以及Unicode库示例

    以vs2012为标准.转自:http://technet.microsoft.com/zh-cn/library/w4zd66ye ,有改动. 一 MFC的静态库(.lib) MFC静态库使用下列命名 ...

  7. 查看静态库(.lib)和动态库(.dll)的导出函数的信息

    From: http://blog.csdn.net/sunliangyuan/article/details/8075808 一般情况下,我们需要查看一个DLL或EXE中的包含的函数或是依赖的函数之 ...

  8. Visual Studio引入外部库 ---- 弄懂静态库lib和动态库dll

    这两天由于想要研究一下socket的相关内容,但是没想到引入外部库还有这么多门道. 根据维基百科定义:一个现代编译器的主要工作流程如下:源代码(source code)→ 预处理器(preproces ...

  9. 【转载】linux静态链接库与动态链接库的区别及动态库的创建

    这篇文章对于动态库的概念及使用介绍的很不错,故收藏了. 一.引言 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数 ...

最新文章

  1. [angularjs] angularjs系列笔记(四)控制器
  2. C/C++头文件大全
  3. python import的一些问题
  4. Bootstrap组件_分页
  5. python 编码声明位置,python中的编码声明
  6. Mac电脑 hbuilderx 运行到小程序node-sass异常
  7. [笔记一]Essential JavaScript Design Patterns For Beginners
  8. HOOK使用:全局键盘钩子
  9. java--idea-生成jar包的配置
  10. 游标需要手动关闭吗MySQL,【MySQL必知必会】使用游标
  11. 团标《智慧高速公路建设总体技术要求》发布征求意见稿
  12. 怎样计算两个文本的Rougel,Bleu评价指标
  13. mybatis_mysql使用 学习笔记
  14. sklearn学习笔记(1)—make_blobs函数及参数
  15. Win10 清空回收站选项点不了怎么解决?
  16. IGBT静态参数测试
  17. android 蓝牙BluetoothAdapter的介绍
  18. 解析:Outlook弹框问题
  19. 爬取猫眼票房保存在MySQL_Scrapy爬取猫眼电影并存入MongoDB数据库
  20. 药检实验室如何规划设计

热门文章

  1. 【python+爬虫】爬去猫眼电影前100名具体信息
  2. linux没有i18n文件,修改linux默认语言i18n
  3. ​【预测模型】基于粒子群算法优化核极限学习机实现数据预测matlab代码
  4. Harris 角点检测(Harris Corner Detection)(OpenCV实现)
  5. python+nodejs+vue社区志愿者活动报名服务管理系统源码
  6. PN通信组态(汇川变频器和S7-1200PN通信)
  7. Ajax的特性以及用法
  8. python-alipay-sdk
  9. DBeaver连接phoenix
  10. 廖雪峰Python学习笔记1