静态库与共享库

来源:互联网 发布: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节,这个节包含动态连接器的路径名。加载器并不是将控制交给应用程序,而是加载和运行动态连接器。

然后动态连接器完成重定位任务,再将控股之传递给应用程序。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果7进海水了怎么办 7p手机进海水怎么办 育海参苗出现红细菌怎么办 苹果手机掉进厕所怎么办 2个月的婴儿肺炎怎么办 甜甜圈珊瑚脱骨怎么办 宝宝吃了生物球怎么办 狗尾巴被剪掉了怎么办 魟鱼尾巴刺了怎么办 狗咬过了24小时怎么办 狗咬超过24小时怎么办 狗咬超过48小时怎么办 狗咬超过72小时怎么办 狗抓超过24小时怎么办 龙须树叶子发黄怎么办? 车被广告牌砸了怎么办 开花店压力好大怎么办 快成熟葡萄软果怎么办 木本叶长白斑点了怎么办 天猫卖家超过72小时未发货怎么办 淘宝超过72小时不发货怎么办 鸿运当头干叶了怎么办 百合枝干长歪了怎么办 植物主干长歪了怎么办 钱兜子花叶子黄怎么办 丝瓜有苦味吃了怎么办 吃了苦的西葫芦怎么办 吃了苦的西葫芦中毒怎么办 吃了一点苦丝瓜怎么办 丝瓜苦味我吃了怎么办? 小孩牙地包天怎么办 小孩的牙地包天怎么办 小孩牙是地包天怎么办 布偶猫生宝宝时怎么办 仔猪拉稀打针喂药都不好怎么办 qq群宠物沉眠怎么办 单位不给开离职证明怎么办 电梯年检报告丢了怎么办 小学生养成夜训交怎么办? 遇到自私多疑的老公该怎么办 老年人吵架非说打她了装病怎么办