Linux中创建和使用静态库&动态库
- 库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行
Linux下库的种类###
- linux下的库有两种:静态库和共享库(动态库)。
- 二者的不同点在于代码被载入的时刻不同。
- 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
- 共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
库文件是如何产生的在linux下
- 静态库的后缀是.a,它的产生分两步
- Step1 由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表
- Step2 ar rcsv 命令将很多.o转换成.a,成为静态库
- 动态库的后缀是.so,它由gcc加特定参数编译产生。
库文件是如何命名的,有没有什么规范
- 在linux下,库文件一般放在/usr/lib和/lib下,
- 静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称
- 动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号,minor是副版本号
创建和使用静态库
下面通过一个简单的例子来说明:
1 首先创建unsgn_pow.c文件
/*unsgn_pow.c:库程序*/
unsigned long long unsgn_pow(unsigned int x,unsigned int y)
{
unsigned long long res = 1;
if (y == 0)
{
res=1;
}
else if (y == 1)
{
res = x;
}
else
{
res = x * unsgn_pow(x,y-1);
}
return res;
}
2 然后创建pow_test.c文件,它会调用unsgn_pow()函数
/*pow_test.c*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
unsigned int x , y;
unsigned long long res;
if ((argc<3) || (sscanf(argv[1],"%u",&x) != 1) || (sscanf(argv[2],"%u",&y)) != 1)
{
printf("Usage: pow base expnent\n");
exit(1);
}
res = unsgn_pow(x,y);
printf("%u ^ %u = %llu\n",x,y,res);
exit(0);
}
3 创建静态库
hh@hh-virtual-machine:~$ gcc -c unsgn_pow.c
hh@hh-virtual-machine:~$ ar rcsv libpow.a unsgn_pow.o
r - unsgn_pow.o
- r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。
默认的 情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。 - c:创建一个库。不管库是否存在,都将创建。
- s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做ar s等同于对该库做ranlib。
- v:该选项用来显示执行操作选项的附加信息。
4 使用静态库(编译主程序,它会链接到刚生成的静态库libpow.a)
hh@hh-virtual-machine:~$ gcc -o pow_test pow_test.c -L. -lpow
hh@hh-virtual-machine:~$ ./pow_test 2 10
2 ^ 10 = 1024
创建和使用动态库
1 首先生成目标文件,但是此时要加编译器选项-fpic和链接器选项-shared
hh@hh-virtual-machine:~$ gcc -fPIC -Wall -c unsgn_pow.c
-wall 允许发出gcc提供的所有有用的报警信息
2 其次生成动态库
hh@hh-virtual-machine:~$ gcc -shared -o libpow.so unsgn_pow.o
生成动态库libpow.so,libpow.so就是我们生成的目标动态库。我们以后使用动态库和main.c程序生成可执行程序
说明:
以上两部也可以合成一步搞定:
hh@hh-virtual-machine:~$ gcc -fpic -shared -o libpow.so unsgn_pow.c
3 使用动态链接库
在编译程序时,使用动态链接库和静态库是一致的,使用”-l库名”的方式,在生成可执行文件的时候会链接库文件。
hh@hh-virtual-machine:~$ gcc -o pow_test pow_test.c -L. -lpow
4 运行
在运行时,程序链接的动态链接库需要在系统目录下才行,所以在运行可执行程序前,需要注册动态库的路径名。
可采用以下几种方式:
a. 在linux下最方便的解决方案是拷贝libPpow.so到绝对目录 /lib 下(但是,要是超级用户才可以,因此要使用sudo)。就可以生成可执行程序了
b.第二种方法是:将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
执行此命令后也可以生成可执行程序。
hh@hh-virtual-machine:~$ cp libpow.so /lib
hh@hh-virtual-machine:~$ ./pow_test 2 10
2 ^ 10 = 1024
hh@hh-virtual-machine:~$
收获
- 主要是对动态链接和静态链接有了更深刻的认识。
- 静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。
- 而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品。
- 静态库与动态库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终的EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
- 采用动态链接库的优点:(1)更加节省内存;(2)DLL文件与EXE文件独立,只要输出接口不便,更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性。
- 动态链接库的两种链接方法:
1 装载时动态链接,这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数,编译时在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中,其主要目的是便于代码共享。
2 运行时动态链接,这种方式是指在编译之前并不知道将会调用哪些DLL函数,完全是在运行过程中根据需要决定调用哪个函数,并用LoadLibrary和GetProc-Address动态获得DLL函数的入口地址。
Linux中创建和使用静态库&动态库的更多相关文章
- 在Linux中创建静态库.a和动态库.so
转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...
- 在Linux中创建静态库和动态库
我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库. 动态库在程序编译时并不会被连接到目标代码中 ...
- 在Linux中创建静态库和动态库 (转)
我们通常把一些公用函数制作成函数库,供其它程序使用.函数库分为静态库和动态库两种.静态 库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.动态库在程序编译时并不会被连接到目标代码中,而 ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- Linux 静态库&动态库调用
1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...
- windows库的创建和使用:静态库+动态库
windows库的创建和使用:静态库+动态库 一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...
- C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项
目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...
- 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释
#1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...
- 生成lua的静态库.动态库.lua.exe和luac.exe
前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...
随机推荐
- 让camera实现类似cs第一人称视角旋转和位移
直接把这个脚本挂在摄像机上就可: using System.Collections; using System.Collections.Generic; using UnityEngine; /* * ...
- 横向排列两个多个div盒子的方法(CSS浮动清除float-clear/inline)/办法
最近在做一个div css切割,昨晚发现了长期以来一直无记录下来的问题!关于兼容IE跟FF的float属性.趁现在还清醒赶紧记下笔记先:一.并排在一行的两个div样式有这种情况:ie或者ff下对于子d ...
- SQL Sever 学习系列之三
SQL Sever 学习系列之三 SQL Server 学习系列之一(薪酬方案+基础) SQL Server 学习系列之二(日期格式问题) 五.经理今天刚谈到with的用法(with的 ...
- Xml日志记录文件最优方案(附源代码)
Xml作为数据存储的一种方式,当数据非常大的时候,我们将碰到很多Xml处理的问题.通常,我们对Xml文件进行编辑的最直接的方式是将xml文件加载到XmlDocument,在内存中来对XmlDocume ...
- bzoj 4503 两个串——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4503 翻转T,就变成卷积.要想想怎么判断. 因为卷积是乘积求和,又想到相等的话相减为0,所以 ...
- BZOJ2054:疯狂的馒头
浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php? ...
- 第六篇 VIM你值得拥有!
vim 是一个具有很多命令的功能非常强大的编辑器.限于篇幅,在本教程当中 就不详细介绍了.本教程的设计目标是讲述一些必要的基本命令,而掌握好这 些命令,您就能够很容易将vim当作一 ...
- AFN 请求数据https
第一步: 导入afn库 第二步: 在pch中添加 #import <SystemConfiguration/SystemConfiguration.h> #import <Mobil ...
- Ext.window.Window
var win = Ext.create("Ext.window.Window", { id: "myWin", title: "示例窗口" ...
- 机器学习:模型泛化(岭回归:Ridge Regression)
一.基础理解 模型正则化(Regularization) # 有多种操作方差,岭回归只是其中一种方式: 功能:通过限制超参数大小,解决过拟合或者模型含有的巨大的方差误差的问题: 影响拟合曲线的两个因子 ...