Linux静态库与动态库

1.GCC编译理论介绍

gcc完成编译需要四部:预处理、编译、汇编、链接。

阶段一预处理:gcc -E test.c -o test.i
阶段二编译: gcc -S test.i -o test.S
阶段三汇编: gcc -c test.S -o test.o
阶段四链接: gcc test.o -o test

在linux中,静态库文件为.a文件 动态库文件为.so文件(与windows中的lib静态库 与dll动态库类似),.a文件为静态链接,在编译的第四阶段一块链接进入主程序,如果静态库改变,则需要一起重新编译;动态库是在执行的时候通过符号表动态链接,动态库改变,接口不变的前提下,则无需重新编译主程序

2.linux静态库的制作与使用

//file list
add.c  add.h   test.c
//add.c
#include "add.h"
int add(int a,int b)
{
 printf("*************add**************\n");
 return (a+b);
}
//add.h
#include <stdio.h>
int add(int a,int b);
//test.c
#include <stdio.h>
#include "add.h"
int main(int argc,char *argv[])
{
  #if 1
  int a = 0,b = 1,sum;

  //sum = a+b;
  sum = add(a,b);
  printf("%s sum = %d\n",__FUNCTION__,sum);
  #endif
  return 0;
}

制作静态库,生成可执行文件

gcc -c add.c -o add.o
ar rc libmyadd.a *.o
gcc test.c libmyadd.a
生成文件
add.c  add.h  add.o  a.out  libmyadd.a  test.c
//执行结果
*************add**************
main sum = 1

静态库其实是由.o文件生成的,可以使用binutils工具readelf、objdump等工具查看.a文件。

readelf -a libmyadd.a
objdump -S libmyadd.a

3.linux动态库的制作与使用

制作动态库,生成可执行文件

gcc -c -fPIC add.c
gcc -shared -fPIC -o libmyadd.so add.o
cp libmyadd.so /usr/lib/libmyadd.so
//默认从usr/lib路径进行查找so文件
gcc -o test test.c  -L. -lmyadd
生成文件
add.c  add.h  add.o  libmyadd.so  test  test.c
//执行结果
*************add**************
main sum = 1

静态库可以隐藏源代码,提高编译的速度,这个.a已经经过了编译汇编的过程。;

动态库同样也可以使用binutils工具进行查看

readelf -a libmyadd.so
objdump -S libmyadd.so

另:
一般在做大型项目时候,会分为多个团队进行负责,会或多或少的使用静态库和动态库。
静态库使用:为隐藏源代码、架构清晰代码分离会考虑使用静态库libtest.a,一般为多个libtest1.a libtest2.a等;
动态库使用:为节省内存等考量会考虑使用动态库libtest.so,一般为多个libtest1.so libtest2.so等,在使用到此模块的时候才会进行加载,不使用便可以进行释放;一般使用
dlopen dlclose进行实现。

4.项目中实际应用动态库

add.c  add.h   test1.c  
//test1.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define LIB_MYADD_PATH "/usr/lib/libmyadd.so" //为动态库的文件路径
typedef int(*ADD_FUNC)(int,int);

int main(int argv,char *argc[])
{
   void* handle;
   char *error;
   ADD_FUNC add_func=NULL;
  //dlopen
  handle = dlopen(LIB_MYADD_PATH,RTLD_LAZY);
  if(!handle)
  {
    fprintf(stderr,"%s\n",dlerror());
    exit(EXIT_FAILURE);
  }
  fprintf(stderr,"%s\n",dlerror());
  *(void**)(&add_func) = dlsym(handle,"add");

  if((error = dlerror())!=NULL)
  {
    fprintf(stderr,"%s\n",dlerror());
    exit(EXIT_FAILURE);
  }
  printf("add: %d\n",(*add_func)(1,2));
  //dlclose
  dlclose(handle);
  exit(EXIT_SUCCESS);
}

制作动态库,生成可执行文件

gcc -shared -fPIC -o libmyadd.so add.o
cp libmyadd.so /usr/lib/libmyadd.so
gcc -rdynamic -o test1 test1.c -ldl
生成文件
add.c  add.h  add.o  libmyadd.so  test1  test1.c 
执行结果与上面是一样的;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值