Linux-动态库和静态库生成和使用

目录

1.GCC编译流程

2.动态库和静态库

3.静态库生成和使用

3.1静态库的生成

 3.2 静态库的使用

4.动态库生成和使用

4.1动态库的生成

 4.2 动态库的使用

4.2.1 动态链接

4.2.2 动态加载

5.工具使用

5.1 nm工具

5.2 ldd命令


1.GCC编译流程

gcc可以让程序员通过它能够更好地控制整个编译过程。

1.预处理阶段(预处理器cpp)

生成i的文件

2.编译阶段(编译器egcs)

将预处理后的文件转换成汇编语言, 生成文件.s

3.汇编阶段(汇编器as)

有汇编变为目标代码(机器代码)生成 .o 的文件

4.链接阶段(链接器ld)

连接目标代码, 生成可执行程序.exe

如图所示:

gcc的常用项如图:

选项名

作用

-c

通知gcc取消连接步骤,即编译源码并在最后生成目标文件

-Dmacro

定义指定的宏,使它能够通过源码中的#ifdef进行检验

-E

不经过编译预处理程序的输出而输送至标准输出

0

获得有关调试程序的详细信息,它不能与-o选项联合使用

-I

在包含文件搜索路径的起点处添加指定目录

-l

提示连接程序在创建最终可执行文件时包含指定的库

-shared

生成共享目标文件。通常用在建立共享库时。

-static

禁止使用共享连接。

-O、-O2、-O3

将优化状态打开,该选项不能与-g选项联合使用

-O0: 不进行优化处理

-O1或者-O: 优化生成代码。

-O2: 进一步优化

-O3:比 -O2 更进一步优化,包括 inline 函数

-S

要求编译程序生成来自源代码的汇编程序输出

-v

启动所有警报

-h

预处理文件(标头文件)

-Wall

在发生警报时取消编译操作,即将警报看作是错误

-w

禁止所有的报警

参考:

1.Linux基础——gcc编译、静态库与动态库(共享库)_daidaihema的博客-CSDN博客_gcc 动态库编译

2.GCC 参数详解 | 菜鸟教程

2.动态库和静态库

区别如下:

静态库

动态库

特点

在链接阶段,将汇编生成的.o文件和引用库一起生成可执行文件,这个方式称之为动态连接。

静态库:libxxxx.a

特点:

1.静态库对函数库的链接是放在编译时。

2.程序在运行时与函数库再无瓜葛

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

动态库:libxxx.so

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

2.可以实现进程之间的资源共享

3.方便程序升级。

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

优点

程序在运行时与函数库没有关系

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

2.可以实现进程之间的资源共享

3.方便程序升级。

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

缺点

1.空间浪费

2.静态库对程序的更新、部署和发布页会带来麻烦

运行时候需要连接库,不存在将报错

备注:inux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

參考:https://www.cnblogs.com/codingmengmeng/p/6046481.html

3.静态库生成和使用

3.1静态库的生成

Linux中的静态库与动态库 - 独孤剑—宇枫 - 博客园

步骤1.书写示例代码:如下add.cpp和mult.cpp头文件和源文件

Add.cpp如下:

#include "add.h"

int add(int a,int b)
{
    return  a+b;
}

Mult,cpp如下:

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

步骤:编译把两个源码文件生成目标文件

gcc   -c  .\add.cpp .\mult.cpp  -I./

步骤,生成静态库:3.使用ar -rsv libxxx.a  *.o制作静态库

ar -rsv    libdemo.a .\add.o .\mult.o

 3.2 静态库的使用

步骤1:书写可执行程序.main.cpp如下

#include <mult.h>
#include <add.h>

int main()

{
    int a=2,b=3;
    cout<<mult(2,3)<<endl;
    cout<<add(2,3)<<endl;
    return 0;
}

步骤2:链接静态库:g++ -o main  .\main.cpp   -L./ -ldemo

步骤3:验证:如下

4.动态库生成和使用

4.1动态库的生成

步骤1和步骤2,和静态库一样,生成.o文件:

步骤3:生成动态库

g++  -shared  -fPIC  -o   libdemo.so  add.cpp   mult.cpp 

 4.2 动态库的使用

4.2.1 动态链接

这个是经常遇见的,步骤1和静态库的使用步骤1相同

步骤2:生成可执行文件

g++  -o main   .\mult.cpp   -L.  -ldemo

4.2.2 动态加载

涉及到函数:

函数原型

说明

const char *dlerror(void)

当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

void *dlopen(const char *filename, int flag)

用于打开指定名字(filename)的动态链接库,并返回操作句柄。调用失败时,将返回NULL值,否则返回的是操作句柄。

void *dlsym(void *handle, char *symbol)

根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。

int dlclose (void *handle)

用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。2.2在程序中使用动态链接库函数。

解析:

函数1:dlsym(void *handle, char *symbol)

filename:如果名字不以“/”开头,则非绝对路径名,将按下列先后顺序查找该文件。

(1)用户环境变量中的LD_LIBRARY_PATH的值;

(2)动态链接缓冲文件/etc/ld.so.cache

(3)目录/lib,/usr/lib

flag表示在什么时候解决未定义的符号(调用)。取值有两个:

1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。

2) RTLD_NOW :表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。

函数2:dlsym(void *handle, char *symbol)

dlsym()的用法一般如下:

void(add)(int x,int y); 说明一下要调用的动态函数add

add=dlsym("xxx.so","add"); 打开xxx.so共享库,取add函数地址

add(89,369); 两个参数89和369调用add函数

步骤1:程序使用demo.cpp:

#include "add.h"
#include <stdio.h>
#include <dlfcn.h>
#include <cstdlib>
extern "C"
{
    typedef  int (*fn)(int a,int b);
}


int main(int argc, char const *argv[])
{
	void *handle = dlopen("libdemo.so",RTLD_LAZY);
	const char *err = dlerror();
	if(err !=NULL){
		perror("could not open shared object!");
	}
	if (NULL != handle) {
		printf("open sussess\n");

	}

	fn  add_func = (fn)dlsym(handle,"add");
	cout<<add_func (23,34)<<endl;
	
	dlclose(handle);
	return 0;
}

步骤2:编译

g++  -g   -o  demo   demo.cpp   -L./   -ldemo  -ldl

步骤3:验证

./demo

如下:

 

5.工具使用

5.1 nm工具

nm可以查看库中有那些函数:列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。

https://www.cnblogs.com/itech/archive/2012/09/16/2687423.html

5.2 ldd命令

可以查看可执行文件或者库连接那些文件,及其连接是否正确

参考:

Linux中的静态库与动态库 - 独孤剑—宇枫 - 博客园

静态库和动态库的区别 - 阿玛尼迪迪 - 博客园

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值