Linux静态库与动态库详解
引言
为了代码的复用性和模块化,我们常常使用一些库文件,在Windows操作系统下位.lib .dll作为静态库和动态库的后缀名。
在Linux下,静态链接库名字一般为libabcdef.a,其中abcdef为该lib的名称
动态链接库名字一般为libabcde.so.major.minor,abcde为该lib的名称,major是主版本号,minor是副版本号
下面来分别介绍一下静态链接库和动态链接库
静态库
- 生成静态库。(以.a为后缀名)
编写如下程序:
/////////////////////////////////////////////////////////////////////////////////////
/* program1. hello.h */
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/* program2. hello.c */
#include <stdio.h>
void hello(const char *name) {
printf("hello, %s\n", name);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/* program3. main.c */
#include "hello.h"
int main(char argc, char *argv[])
{
hello("world");
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////
编译hello.c,生成一个可重定位的目标文件hello.o
$gcc -c hello.c
Linux环境下使用ar工具创建一个静态库,或者将目标文件加入到一个已经存在的静态库中。并使用方法如下:
$ar rcs 静态库名 目标文件1 目标文件2...目标文件n
该明亮表示将目标文件1~n加入到指定的静态库中。如果该静态库不存在,则创建静态库文件,并且将库文件的扩展名
命名为.a,其中ar工具的参数rcs弃了至关重要的作用。这3个参数分别表示:把列表中的目标文件加入到静态库中(参数r);
若指定的静态库不存在,则创建该库文件(参数c);最后更新静态库文件的索引,使之包含新加入的目标文件的文件内容(参数s).
现在,我们需要使用刚生成的hello.o目标文件,创建一个静态库文件libmyhello.a,其执行命令如下:
$ar rcs libmyhello.a hello.o
静态库制作完毕以后,可以看到在当前目录下生成了libmyhello.a文件
备注:在某些系统中还要为静态库生成一个内容表
$ranlib libmyhello.a
- 使用静态链接库
在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成可执行文件时,指明静态库的名字。
gcc将会从静态库中将公用函数连接到目标文件中。
备注:gcc会在静态库名前加上前缀lib, 然后追加扩展名.a得到的静态库文件名来查找静态库文件。因此,我们在写需要连接到库时,
只写名字就可以。如libmyhello.a的库,只写-lmyhello
$gcc main.c -L. -lmyhello
可以看到编译通过,并在当前目录下生成a.out可执行文件,执行可执行文件,即可生成hello, world
如果想在编译的时候修改可执行文件的名字,可以使用如下命令:
$gcc main.c -L. -lmyhello -o x_main
使用gcc的-l选项来指定静态库,或者使用-L参数来指定库文件的搜索路径。
-l和-L之后都直接带参数而不跟空格。因此,这里“."作为静态库的搜索路径。
注意:在使用gcc链接静态库的时候的,其参数的顺序。
-l是链接器选项,一定要放在被编译的源文件的文件名称之后,也就是本例中的main.c文件之后。若放在文件名称之前,则会链接失败。
gcc也支持使用-static选项对静态库进行链接。
因为静态库是直接编译到可执行文件中,我们可以删除掉当前目录下的libmyhello.a文件,
然后重新执行可执行文件,可以看到:程序的结果与之前一样,表明静态库文件已经成功链接到可执行文件中了。
静态链接库的缺点:
如果我们同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一个库函数。这样就会浪费掉很多珍贵的内存和存储空间。
使用动态链接库就可以避免这个问题。
当静态库与动态库同名时,gcc命令默认将优先使用动态库。
动态库(未验证)
1.在程序中使用动态库
(1)如果是标准C语言库我们可以不指定其库路径和库名称
(2)如果静态库处于/lib或/usr/lib下
$gcc -o test test.c /usr/lib/libm.a 或 $gcc -o test test.c -lm
他们的效果相同。-lm意味着命名为libm.a或libm.so的文件(注意Linux下的库文件都要以lib开头)。
参考:
《Linux C程序设计大全》吴岳等编著
https://wenku.baidu.com/view/7d8602b265ce050877321301.html
http://general.blog.51cto.com/927298/269044
Linux静态库与动态库详解的更多相关文章
- JNI静态注册与动态注册详解
JNI注册,是指将java层方法(native关键字修饰的)和C层方法对应起来,以实现java层代码调用c层代码的目的.JNI注册分为静态注册和动态注册两种,静态注册是通过固定格式方法名进行关联,动态 ...
- Apache静态编译与动态编译详解
Apache拥有4层结构,从核心到外层的module.而外层的module可以用通过静态和动态两种方式与Apache共同工作.这也就引入下文的“动态”和“静态”两种编译安装方式: 静态编译: 编译的时 ...
- 技巧:Linux 动态库与静态库制作及使用详解
技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...
- Linux下Gcc生成和使用静态库和动态库详解(转)
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- Linux下Gcc生成和使用静态库和动态库详解
参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...
- 【转】Linux下gcc生成和使用静态库和动态库详解
一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...
- (笔记)Linux下的静态库和动态库使用详解
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比 ...
- 深入探讨Linux静态库与动态库的详解(转)
2.生成动态库并使用 linux下编译时通过 -shared 参数可以生成动态库(.so)文件,如下 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静 ...
- Linux-Gcc生成和使用静态库和动态库详解
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
随机推荐
- 常见企业IT支撑【1、办公网络IP地址规划】
规划思路如下,可灵活变化
- C# datatable竖行转换的问题
这次在做项目中,遇到了这样一个问题:datable中列头的名字是不确定的,从数据库中动态查出来的,假设为typeDATA,行的数据中又包含了列头的信息,并按固定的字段分组,当查处行的数据之后用来填充每 ...
- js 日期正则 转载
天秤水的Blog 博客园 博问 闪存 首页 新随笔 联系 管理 订阅 随笔- 70 文章- 0 评论- 74 最强日期正则表达式 一.简单的日期判断(YYYY/MM/DD): ^\d{ ...
- 查询oracle安装过补丁没有
[oracle@root ~]$ opatch lsinventoryInvoking OPatch 10.2.0.1.0 Oracle interim Patch Installer version ...
- SQL分组查询及聚集函数的使用
今天要做一个查询统计功能,一开始有点犯难,上午尝试大半天才写出统计sql语句,才发现自己sql分组查询及聚集函数没学好:其实就是group by子句和几个聚集函数,熟练使用统计功能很简单.在此总结下今 ...
- Java 编译???
如果是在命令行下,编译就是 javac a.java 如果有错误,那么命令运行之后会显示错误 但是在eclipse下,我都是直接点击运行按钮的,如果有错误,在编程是就提示了,那么是怎么编译的呀 大的工 ...
- 从windows拷贝到linux的脚本报错:未找到命令 or 语法错误
可能真的是命令拼错了或者参数有误,也可能是语法错误. 但是但是但是,如果之前脚本运行的好好的,没做任何改动或者仅仅改了一丁点儿. 那么脚本可能在格式上存在问题,解决方案: 安装dos2unix sud ...
- 华为交换机S5700 vty 0 4
最佳答案 vty 0 4 代表有5条VTY线路 由0到4 这个要看设备的版本有的设备会有更多条VTY线路比如一些企业版的设备 显示用户界面 进入TELNET 设置模式 user-interface ...
- python socket打造一个定位工具
前言: 刚刚学习socket,打算后期得学习 怎么写exploit. 原理: 其实很简单,客户端写个爬虫.然后将获取到的IP放入高德地图 在通过socket发送.利用ngrok达到能外网搞事. 准备: ...
- Mysql总结(二)
数据库.表.字段.行 问:查询姓黄或洪的男生分析:数据从哪来,哪个表stu条件:姓黄或洪name or and 男生gender答:select * from stu where gender=1 a ...