Linux 静态库与共享库的使用
申明: 正如题如示,本篇讲的是Linux下是静态库与共享库,而Window下的动态链接库详细情况可见这篇文章:windows动态链接库 DLL 浅析。虽然原理,思想差不多,但是细节却各有不同。
一、静态库
:静态库指将所有相关的目标文件打包成为一个单独的文件-即静态库文件,以.a结尾。静态库可作为链接器的输入,链接器会将程序中使用的到函数的代码从库文件中拷贝到应用程序中。一旦链接完成,在执行程序的时候就不需要静态库了。
存档文件是一组连接起来的可重定位目标文件的集合,有一个头部用来描述每个成员目标文件的大小和位置(存档文件名由后缀.a标识)。
// addvec.c
void addvec(int* x, int* y, int*z, int n)
{
int i=0;
for(; i< n;++i)
z[i] = x[i] + y[i];
}
// multvec.c
void multvec(int*x, int* y, int* z, int n)
{
int i = 0;
for(; i < n; ++i)
z[i] = x[i] * y[i];
}
使用这个库,编写一个应用(其调用addvec库中的函数):
/* main2.c */
#include <stdio.h> int x[2] = {1, 2};
int y[2] = {3, 4};
int z[2]={0}; int main()
{
addvec(x, y, z, 2);
printf("z = [%d %d]\n", z[0], z[1]);
return 0;
}
链接-
运行程序:
-static 参数告诉编译器驱动程序,链接器应该构建一个完全的可执行目标文件,它可以加载到存储器并运行,在加载时无需进一步的链接 -
即一次性静态链接完毕,不允许存在动态链接。
:共享库是一个目标模块(以.so后缀表示),在运行时,可以加载到任意的存储器地址,并和一个在存储器中的程序链接起来,这个过程称为动态链接,是由一个叫做
动态链接器
的程序来执行的。
根据加载和链接共享库的时机又可分为:A)应用程序
自身加载时
动态链接和加载共享库;B)应用程序
运行过程中
动态链接和加载共享库两种情况。
-shared选项来指示链接器创建一个共享的目标文件(即共享库),链接并运行程序:
-fPIC选项指示编译器生成与位置无关的代码
- 1)重定位libc.so的文本和数据到某个存储器段;
- 2)重定位libvector.so的文本和数据到另一个存储器段;
- 3)重定位p2中所有对libc.so和libvector.so定义的符号的引用。
从这个时刻开始,共享库的位置就固定了,并在在程序的执行过程中都不会再改变!
在运行过程中要求动态链接器加载和链接任意共享库,而无需编译时链接那些库到应用中。
#include<dlfcn.h> /* 加载和链接共享库 filename
filename:共享库的名字
flag有:RTLD_LAZY, RTLD_NOW,二者均可以和RTLD_GLOBAL表示取或
*/
void *dlopen(const char *filename, int flag); // 若成功则返回执行句柄的指针,否则返回NULL /*根据共享库操作句柄与符号,返回符号对应的地址
handle:共享库操作句柄
symbol:需要引用的符号名字
*/
void *dlsym(void *handle, char *symbol); // 若成功则返回执行符号的指针(即地址),若出错则返回NULL /* 如果没有程序正在使用这个共享库,卸载该共享库 */
int dlclose(void *handle); // 若卸载成功,则返回0,否则返回-1 /* 捕捉最近发生的错误 */
const char *dlerror(void); // 若前面对dlopen,dlsym或dlclose调用失败,则返回错误消息,否则返回NULL
例子:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h> int x[2] = {1, 2};
int y[2] = {3, 4};
int z[2] ={0}; int main()
{
void *handle;
void (*addvec)(int *, int *, int *,int);
char *error; handle = dlopen("./libvector.so", RTLD_LAZY);
if(!handle){
fprintf(stderr, "%s\n", dlerror());
exit(1);
} addvec = dlsym(handle, "addvec");
if((error = dlerror()) != NULL){
fprintf(stderr, "%s\n", dlerror());
exit(1);
} addvec(x, y, z, 2);
printf("z = [%d %d]\n", z[0], z[1]); if(dlclose(handle) < 0){
fprintf(stderr, "%s\n", dlerror());
exit(1);
} return 0;
}
运行结果:
-ldl参数:表示生成的对象模块需要用到共享库
Referebces:
1.《深入理解计算机系统》第7章:链接 P448-P479
2. 静态库、共享库、动态库的创建和使用 :http://bbs.chinaunix.net/thread-2037617-1-1.html
3. Linux 动态库剖析:http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/
Linux 静态库与共享库的使用的更多相关文章
- 【转】Linux 静态库与共享库的使用
原文网址:http://blog.csdn.net/heyabo/article/details/11688517 申明: 正如题如示,本篇讲的是Linux下是静态库与共享库,而Window下的动态链 ...
- linux下的静态库和共享库
转载&&增加: 我们在编写一个C语言程序的时候,经常会遇到好多重复或常用的部分,如果每次都重新编写固然是可以的,不过那样会大大降低工作效率,并且影响代码的可读性,更不利于后期 ...
- Linux下库的制作(静态库与共享库)
库中实际上就是已编译好的函数代码,可以被程序直接调用. Linux下的库一般的位置在/lib或者/usr/lib中 静态库 静态库是复制拷贝到调用函数中的,函数运行的时候不再需要静态库,因为静态库是在 ...
- 第二课 GCC入门之静态库以及共享库
序言: 前面一课讲了gcc的简单入门,包括gcc编译步骤:预处理:编译:汇编:链接.今天这节课就来讲下linux的库也欢迎大家吐糟共同学习. 原理: linux系统中分为2种库:静态库和共享库.静态库 ...
- Linux下Qt创建共享库与链接共享库详解
随着程序写的逐渐变多,或多或少的我们都会使用别人写好的库:或者我们不想让别人看到我们的一些核心程序,可以将核心程序封装成库.本次和大家分享的是在Ubuntu下使用Qt生成共享库以及在Qt中链接共享库的 ...
- Linux静态库和共享库
1.什么是静态库静态库类似windows中的静态lib 关于windows中的静态lib,可参考 Windows动态链接库DLL 特点:包含函数代码声明和实现,链接后所有代码都嵌入到宿主程序中. 只在 ...
- Linux静态库和共享库【转】
转自:http://www.cnblogs.com/zlcxbb/p/6806269.html 1.什么是静态库 静态库类似windows中的静态lib 关于windows中的静态lib,可参考 Wi ...
- Linux命令(十二)制作静态库和共享库
1. 静态库 静态库文件命名:libxxxx.a 1.1 步骤: ar rcs libCalc.a *.o 1.2 用nm查看文件内容 1.3 发布并使用 gcc main.c -o mycpp.ou ...
- gcc创建静态库和共享库
静态库和动态(共享)库静态库:编译程序在编译使用库提供的功能代码的程序时将代码复制到该程序然后编译成可执行程序,这种库成为静态库共享库:共享库比静态库的处理方式更加灵活,因而其产生的可执行文件更小,其 ...
随机推荐
- DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建
这个系列通过一些简单例子循序渐进,介绍DevExpress ASP.NET控件的使用.先来介绍一下XPO的使用,安装的DevExpress版本为DXperienceUniversal-12.2.4,使 ...
- Android乐学成语之自定义Adapter
一.首先对Adapter概念深刻的了解 首先看看他的继承图
- SERVLET API 中 forward() 与 redirect()的区别?
答:前者仅是容器中控制权的转向, 在客户端浏览器地址栏中不会显示出转向后的地址: 后者则是完全的跳转, 浏览器将会得到跳转的地址, 并重新发送请求链接. 这样, 从浏览器的地址栏中可以看到跳转后的链接 ...
- Junit 测试常见错误
1. java.lang.Exception: No tests found matching Method deleteUser(mybatis.dao.Usertest) from org.jun ...
- Sliding Window Maximum
(http://leetcode.com/2011/01/sliding-window-maximum.html) A long array A[] is given to you. There is ...
- 操作百度API
string json = ""; try { //虽然两者都是异步请求事件,但是WebClient是基于事件的异步,而HttpWebRequst是基于代理的异步编程 WebCli ...
- JQuery中判断checkbox是否选中与禁用鼠标右键
if ($("#wds_checkbox").attr("checked")) { flag = ; } else { flag = ; } 禁用鼠标右键 // ...
- Spring Annotation vs XML - 示例
来源: http://hanqunfeng.iteye.com/blog/2113820 作者hanqunfeng的示例文件: (可下载) web-mvc.zip
- Sqoop mysql 数据导入到hdfs
1.--direct 模式使用mysqldump 工具,所以节点上需要安装该工具,非direct 模式直接使用jdbc ,所以不需要 具体script参考如下: sqoop import --conn ...
- PHP的环境搭建
下载开发环境 wampserver 下载sublime text 2 sublime使用技巧 1:安装漂亮的编程字体http://pan.baidu.com/s/1xMex9 下载"程序编写 ...