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 ...
随机推荐
- bzoj4513 储能表
求 $\sum\limits_{i=0}^{n-1} \sum\limits_{j=0}^{m-1} max((x \space xor \space j) - k,0)$ ,膜 $p$ $n,m \ ...
- Milking Time(DP)
个人心得:一开始自己找状态,是这么理解的,只要前面一个满足就等于此时的值加上d(n-1),否则就是不挖此时的比较d(n-1)和 d(n-2)+cost,不过仔细一想忽略了很多问题,你无法确定n-2和此 ...
- 【LeetCode】003. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- poj 2262 Goldbach's Conjecture——筛质数(水!)
题目:http://poj.org/problem?id=2262 大水题的筛质数. #include<iostream> #include<cstdio> #include& ...
- IEEE1588精密网络同步协议(PTP)
1 引言 以太网技术由于其开放性好.价格低廉和使用方便等特点,已经广泛应用于电信级别的网络中,以太网的数据传输速度也从早期的10M提高到100M,GE,10GE.40GE,100GE正式产品也于20 ...
- PHP:json_encode 保持中文不被转为ASCII码
echo json_encode(array('黄河之水天上来'),JSON_UNESCAPED_UNICODE);
- HDOJ4768(二分区间)
Flyer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- STM32 -- 硬件知识
一.网站资源 1.http://www.stmcu.com.cn/ 二.硬件 1.BOOT0 和 BOOT1 1)一般BOOT0和BOOT1跳线都跳到0(地): 只是在ISP下载的情况下,BOO ...
- [转载]关于linux下system()函数的总结
1.曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.这里必须要搞懂system()函数,因为有时你不得不面对它. 2.先来看一下system()函数的简 ...
- 机器学习:模型泛化(LASSO 回归)
一.基础理解 LASSO 回归(Least Absolute Shrinkage and Selection Operator Regression)是模型正则化的一定方式: 功能:与岭回归一样,解决 ...