linux系统编程+网络编程

C++静态库与动态库
黑马程序员-Linux系统编程
黑马程序员-Linux网络编程

g++编译4步骤

在这里插入图片描述
Build和Make意味着编译项目中所有源代码文件的代码,通常是一个递增过程,如果项目中有3个文件,只有1个文件被修改,只重新编译该文件。
Build All重新编译所有的源代码文件

g++ 编译参数

-I 指定头文件所在目录位置
-c 只做预处理,编译,汇编。得到二进制文件
-g 编译时添加调试文件,用于 gdb 调试
-Wall 显示所有警告信息
-D 向程序中“动态”注册宏定义
-l 指定动态库库名
-L 指定动态库路径

库是一种可执行代码的二进制形式
库有两种:静态库(.a、.lib)和动态库(.so、.dll)
在这里插入图片描述

静态库

链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中
静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似
一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件
Linux下使用ar工具、Windows下vs使用lib.exe,将目标文件压缩到一起,并且对其进行编号和索引,以便于查找和检索
在这里插入图片描述
如何使用呢?
首先编写静态库代码

a.h

#pragma once  // 防止多次导入
class StaticMath
{
public:
	StaticMath();
	~StaticMath();

	static int add(int a, int b);  // 声明为静态函数不用创建对象即可使用该方法
	static int sub(int a, int b);
};

a.cpp

#include <iostream>
#include "a.h"
int StaticMath::add(int a, int b)
{
	return a + b;
}

int StaticMath::sub(int a, int b)
{
	return a - b;
}

命令:

// 将代码文件编译成目标文件.o
g++ -c a.cpp
// 静态库名字以 lib 开头,以.a 结尾,通过ar工具将目标文件打包成.a静态库文件
ar rcs liba.a a.o

编写测试代码 b.cpp :

#include "b.h"
#include "a.h"
#include <iostream>
using namespace std;
int main()
{
	int a, b;
	cin >> a >> b;
	cout << StaticMath::add(a, b) << endl;
	cout << StaticMath::sub(a, b) << endl;
	return 0;
}

命令:

// 指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)
g++ b.cpp liba.a -o b

还可以将多个源代码变为一个静态库进行操作:
编写两个源代码:
a.h

#pragma once
int add(int a, int b);

a.cpp

#include "a.h"
int add(int a, int b)
{
	return a + b;
}

b.h

#pragma once
int mul(int a, int b);

b.cpp

#include "b.h"
int mul(int a, int b)
{
	return a * b;
}

命令:

g++ -c a.cpp b.cpp
ar rcs libaddandmul.a a.o b.o

编写测试代码:
c.h

#pragma once
#include "a.h"
#include "b.h"

c.cpp

#include <iostream>
#include "c.h"
using namespace std;
int main()
{
	int a, b;
	cin >> a >> b;
	cout << add(a, b) << endl;
	cout << mul(a, b) << endl;
	return 0;
}
g++ c.cpp libaddandmul.a -o c

动态库

不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。
在这里插入图片描述
动态库把对一些库函数的链接载入推迟到程序运行的时期
可以实现进程之间的资源共享。(因此动态库也称为共享库)
将一些程序升级变得简单
甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)
在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数做出初始化的入口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。
Linux下gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要函数做特别的声明,编写比较方便。
不需要打包工具(ar、lib.exe),直接使用编译器即可创建动态库
动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为“.so”
制作动态库的步骤:
源代码依旧使用上文中的 a.cpp 和 b.cpp,生成位置无关的.o 文件

g++ -c a.cpp b.cpp -fPIC
gcc -shared -o libmy.so a.o b.o
g++ c.cpp -o c -lmy -L.
./c

执行出错,加载共享库时:libmy,不能打开共享对象文件:没有这样的文件或目录
出错原因分析:
连接器: 工作于链接阶段,工作时需要 -l 和 -L
动态链接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置
指定动态库路径并使其生效,然后再执行文件
通过环境变量指定动态库所在位置:export LD_LIBRARY_PATH=动态库路径
环境变量是进程的概念,关闭终端之后再打开,是两个进程,环境变量发生了变化。
要想永久生效,需要修改 bash 的配置文件:vi ~./bashrc
修改后要使配置文件立即生效:. .bashrc 或者 source .bashrc 或者重开终端让其自己加载

makefile 基础规则

协议

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值