当前课程知识点:基于Linux的C++ >  第十二讲 Linux系统编程基础 >  12.10 库(一) >  LinuxCPP1210

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1210在线视频

LinuxCPP1210

下一节:LinuxCPP1211

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1210课程教案、知识点、字幕

接下来一节就是库

我们在编写实际程序代码的时候

我们总是将我们的程序

分解成一个又一个的模块的架构

这些模块就是所谓的库

我们实际在编写这个程序的时候

这些库总是和我们的程序

一并编译的 但实际上

这些库本身可以被单独地编译

就像我们的标准库一样

在设计标准库的时候

那些 C/C++ 的发明者 包括库的设计者

那些 C/C++ 的发明者 包括库的设计者

并不知道我们要使用这个库解决什么问题

并不知道我们要使用这个库解决什么问题

所以那个库的编译

它是单独的

库可以被单独地编译

编译出来的结果呢

可以是静态库 也可以是动态库

如果是静态库

我们编译出来的库

后缀的名字一般都是 “.a”

叫 archives 静态库

我写了一个库

这个库里边包括了一系列的函数

甚至可能包括一系列的类

并没有主程序 特别注意这一条

我单独地对它们进行编译

形成目标文件 就是一系列的 “.o”

然后我们可以使用 ar 这个命令

来构造一个单独的静态库

构造这个静态库的时候

可以使用多个目标文件

这个没有问题

我们可以使用 ar cr 参数

表示要创建一个静态库

库的名字呢叫 “libtest.a”

使用哪两个目标文件呢

使用 “test1.o”、“test2.o”

用这两个目标文件构造一个静态库

就按照这个方式编译和链接

就可以形成我们的静态库

链接器在编译我们的程序

链接代码的时候

那么它搜索静态库

就会链接所有已经解析出来的

我们引用了但是还没有被实现的函数

我们引用了但是还没有被实现的函数

就会从静态库里把那个代码抽出来

放到我们的可执行文件里

这就是静态库

在链接静态库的时候

同学们要注意

静态库的链接本身

应该放置在我们链接命令的末尾

当我要编译我们的程序

要使用到别人已经实现好的这个静态库

我想链接它 那么这个静态库的链接

就应该放在我们命令行的末尾

要保证我们的程序能够正确地解析到库的代码

要保证我们的程序能够正确地解析到库的代码

你放在前面

它就不一定能够解析得到

越放在后 它是越容易被解析

因为前面所有需要用到它的

都能够查到它 它知道要用

所以后面就会去把它抽出来了

就这个意思 这个是静态库

我们还可以实现动态库

动态库它的称呼就叫 shared object

严格讲起来应该叫共享目标库

这样的共享目标库呢

就类似于 Windows 下面的动态链接库 DLL

它实际上也是动态链接的

后缀一般是 “.so”

共享目标 就这个意思

我们使用编译命令 “g++ -shared -fPIC -o”

我们会输出我们的共享目标库

动态库的名字叫 “libtest.so”

我们编译它的时候

我们使用动态链接的方式编译

所以这样的库的编译

必须使用 “-shared” 选项

表示要生成一个共享的动态库

共享目标库 就这个意思

我们要用一个 “-fPIC” 选项

来表示生成的目标代码

它是个位置无关代码

所有的共享目标库理论上

都应该是位置无关的

因为我们需要确保这样的动态库

能够在合适的时候

被装载到内存的特定的位置

而我们事先无法为这样的动态库的装载位置指定确定的范围

而我们事先无法为这样的动态库的装载位置指定确定的范围

因为每次装载的情况可能都不一样

每一个进程装载同样库的时候

它的位置可能也不一样

所以代码本身应该是位置无关的

就是所有的引用都应该是相当于它这个库的起始地址

就是所有的引用都应该是相当于它这个库的起始地址

而不是它真实的物理内存的绝对的物理地址 就这个意思

而不是它真实的物理内存的绝对的物理地址 就这个意思

这叫位置无关代码

当你编译动态库的时候

就应该按照这样方式进行实现

对于编译器来讲

当我们真正地要使用到别人库的时候

那么它首先会尝试着链接动态库

需要的时候它会把动态库的代码

装到内存里面运行

所以首先链接的就是动态库

没有动态库

才会尝试着链接我们的静态库

链接静态库

就会将那段代码从静态库中抽出来

放到我们的可执行文件里

静态库就会导致我们的可执行文件代码膨胀

静态库就会导致我们的可执行文件代码膨胀

所以它首先链接的是动态库

其次才是静态库

如果你需要你的程序

强制地链接静态库

那么你就应该使用 “-static” 选项

来编译你的程序

这是静态库和动态库的基本概念

在 C/C++ 代码里边它提供的标准库

C 的标准库名字叫 “libc”

C++ 的标准库叫 “libstdc++”

这两个库的名字是固定的

你必须按照这样的方式去使用标准库

但是在 Linux 操作系统中

有一点比较特殊

就是数学库本身是单独的

它用 “libm” 来表示数学库

所以如果你需要链接的时候呢

它并不缺省地链接数学库

在需要的时候

你必须显示地链接数学库

就当你需要使用数学函数 好吧

你需要链接数学库

那么就要在末尾写 “-lm”

表示把这个数学库链接进去

“-l” 就表示链接一个特定的库

后面跟着就是它的库的名字

“lib” 那三个字符就可以省略

这个库的名字叫 “libm”

所以你只需要写 “m” 就行了

“-lm” 就表示链接那个数学库

按照这个格式

但是如果你要编译 C++11 的程序

那这个情况就有点特殊

因为不是每一个 gcc 的程序

它都能够编译 C++11 的代码的

所以正常情况下面

我们可能使用 4.8 以后 g++ 版本

所以你可能使用的那个编译命令叫 g++-4.8

所以你可能使用的那个编译命令叫 g++-4.8

这是我们的编译器

使用 4.8 版本的 g++

以上的版本其实都可以

现在我们可能还用 4.9

OK 我们 g++-4.8 用它来编译

我们的 C++11 代码

然后记得在后面加一个选项 “-std=c++11”

然后记得在后面加一个选项 “-std=c++11”

表示使用 C++11 的库

而不是使用 C++ 标准库

注意这个 “c” 是小写的 “c”

不是大写的 “C”

你必须按照这个格式来

这是命令行编译的时候

你需要做的事

但实际上 我们现在开发 Linux 程序

有相当多的集成开发环境

最常见地 你比如说 Code::Blocks

你在 Code::Blocks 集成开发环境里

编写 C++11 的程序的话

那么很典型

它里面有一个编译选项

你把它 C++11 的那个特性给打开

就自动地替你链接 C++11 库

如果你不打开

它就链接 C++ 标准库

处理模式就方便了很多

在实际编程的时候

我们可能需要链接好多个库

这些库之间可能具有特定的相关性

这些库之间可能具有特定的相关性

你比如讲

我们需要写一个图像处理的程序

这个图像处理程序呢

需要处理我们的 tiff 图像

那么就需要链接 libtiff 这个库

而 libtiff 这个库

它是 libjpeg 这个库和 libz 这个库是相关的

所以链接的时候要特别注意

libtiff 要放在前边

libjpeg 和 libz 这两个库要放在后边

那你链接的时候就应该这么写

“g++ -static -o tifftest tifftest.c -ltiff -ljpeg –lz”

你按照这个格式去链接这三个库

如果有一种情况

一个库需要另外一个库

而另外一个库又需要它

它是交叉地相关的

那么碰到这种情况

这样的两个库链接的时候

就需要特别注意

我们要重新写一遍

“g++ -o app app.o -la -lb -la”

这样的话

a 库要使用 b 库的代码

那么它就能够从 b 库里面

把这个代码抽取出来

如果 b 库又要使用 a 库的代码呢

你要重复写一遍 “-la”

那么 b 就能从 a 库里面

把它需要的代码也抽取出来

完成这样的交叉的库的相关性

就必须使用这个模式

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1210笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。