静态库与共享库
来源:互联网 发布:mysql join as 编辑:程序博客网 时间:2024/06/15 03:14
1. 静态库:
所有编译器都提供一种机制,将所有相关的目标文件模块儿打包成一个单独的文件,被称为静态库。它可以用作来连接器的输入,当连接器构造一个输入的可执行文件时,它只拷贝静态库里面被应用程序引用的模块儿。
在unix系统中,静态库以存档(一组连接起来的可重定位目标文件的集合,有一个头部来描述成员目标文件的大小和位置)的文件格式存在于磁盘中。
使用静态库的例子:
(1)addvec.c文件
void addvec(int *x,int *y,int *z,int n)
{
inti;
for(i= 0;i < n;i++)
z[i]= x[i] + y[i];
}
(2)multvec.c文件:
void multvec(int *x,int *y,int *z,int n)
{
inti;
for(i= 0;i < n;i++)
z[i]= x[i] * y[i];
}
(3)用vector.h文件声明两个函数的原型:
void addvec(int *x,int *y,int *z,int n);
void multvec(int *x,int *y,int *z,int n);
(4)用AR工具创建静态库libvector.a:
gcc–c addvec.c multvec.c
arrcs libvector.a addvec.o multvec.o
(5)main.c文件:
#include<stdio.h>
#include"vector.h"
int main()
{
intx[2]={1,3};
inty[2]={3,4};
intz[2];
addvec(x,y,z,2);
printf("z=[%d %d]\n",z[0],z[1]);
return0;
}
(6)编译运行:
gcc –O2 –c main.c
gcc –static –o p2 main.o ./libvector.a
-static参数是告诉编译器驱动程序,连接器应该构建一个完全链接的可执行目标文件,它可以加载到存储器并运行,在加载时无需更进一步的来链接。
2:共享库:
动态链接:共享库,在运行时,可以加载到任意的存储器地址,并和一个在存储器中的程序链接起来。(动态链接由动态连接器执行)
共享库也称为共享目标,在unix系统中用.so后缀表示,微软中使用共享库陈伟DLL(动态共享库);
共享库的两种共享方式:(1)在任何系统中,对于一个库只有一个.so文件,所有引用该库的可执行目标文件共享这个.so文件中的代码和数据,而不是像静态库一样将引用的内容拷贝和嵌入到可执行程序中。(2)在存储器中,一个共享库的.text节的一个副本可以被不同的正在运行的进程共享。
共享库的加载时间:(1)在应用程序执行之前,也就是说在应用程序被加载的时候,动态加载器加载和链接任意共享库(2)应用程序在运行时要求动态加载器加载和链接任意共享库,而无须在编译时链接哪些库到应用中。(unix提供了一个接口,允许应用程序在运行时加载和链接共享库)
#include<dlfcn.h>
void*dlopen(const char * filename,int flag);
成功返回句柄的指针,失败返回NULL.
Flag参数:(1)RTLD_NOW:告诉连接器立即解析对外部符号的引用。(2)RTLD_LAZY:高速连接器推迟符号解析直到执行来自库中的代码。
#include<dlfcn.h>
void*dlsym(void *handle,char *symbol);
成功返回指向符号的指针,出错为NULL,第一参数是前面已经打开的共享库的句柄,第二个参数是一个符号的名字
#include<dlfcn.h>
Intdclose(void *handle);
成功返回0,出错返回-1,没有其他共享库正在使用这个共享库,dlclose函数就卸载该共享库
#include<dlfcn.h>
constchar *dlerror(void);
对于dlopen,dlsym,dlclose的调用失败,则返回出错信息,成功,则返回NULL
例子:
(1) 生成共享库:
gcc –shared –fPIC –o libvector.so addvec.cmultvec.c
-fPIC:告诉编译器生成与位置无关的代码。
(2) main1.c文件:
#include<stdio.h>
#include<stdlib.h>
#include<dlfcn.h>
intx[2]={1,2};
inty[2]={3,4};
intz[2];
intmain()
{
void *handle;
void (*addvec)(int *,int *,int *,int);
char *error;
/*Dynamiically load shared library thatcontains addvec*/
handle =dlopen("./libvector.so",RTLD_LAZY);
if(!handle){
fprintf(stderr,"%s\n",dlerror());
exit(1);
}
/*Get a pointer to the addvec() function wejust loaded*/
addvec = dlsym(handle,"addvec");
if((error = dlerror()) != NULL){
fprintf(stderr,"%s\n",error);
exit(1);
}
/*Now we can call addvec() just like anyother function*/
addvec(x,y,z,2);
printf("z = [%d%d]\n",z[0],z[1]);
/*Unload the shared library*/
if(dlclose(handle) < 0){
fprintf(stderr,"%s\n",dlerror());
exit(1);
}
}
(3) 运行编译:gcc –rdynamic –O2 p3 main1.c –ldl
–rdynamic参数,告诉编译器,对于符号解析而言,全局符号也可用。
注意:如gcc -0 p2 main1.c./libvector.a,创建一个p2的慕白哦文件。这个文件运行时可以和libvector.a链接。
创建可执行文件时,静态执行一些链接,程序加载时,动态完成链接过程。
加载器加载运行p2时,p2包含一个.interp节,这个节包含动态连接器的路径名。加载器并不是将控制交给应用程序,而是加载和运行动态连接器。
然后动态连接器完成重定位任务,再将控股之传递给应用程序。
- 静态库与共享库
- 静态库与共享库
- 静态库与共享库
- 静态库与共享库
- 静态库与共享库
- 静态库与共享库
- 静态库与动态库(共享库)
- Linux 静态库与共享库
- Linux 静态库与共享库
- Linux 静态库与共享库
- Linux 静态库与共享库
- linux 静态库与共享库
- linux静态库与共享库
- linux静态库与共享库
- day_02_静态库与共享库
- 静态库,共享库
- 静态库与共享库制作与应用
- GCC与静态库、共享库以及动态加载库
- angular.js模态框拖动(2)
- Go游戏服务器开发的一些思考(十):goroutine和coroutine
- 配置lamp环境
- mysql优化,不用怕面试题了
- sqlserver突然出现“远程过程调用失败”
- 静态库与共享库
- 牛顿法
- CheckBox选择按钮
- 生成素数表
- centos安装GrayLog
- JAVA学习路线图
- 最近总结--Bootstrap相关
- 数据库基础(第一到六章节)
- java中的初级ATM模拟