静态库和动态库的生成

版权声明:本文为博主原创文章,欢迎转载,转载请声明出处! https://blog.csdn.net/hansionz/article/details/83241499

一.什么是静态库和动态库

1.静态库

静态库是程序在编译链接时把库的代码链接到可执行文件中去。程序运行的时候不需要依赖库。它以.a结尾。

2.动态库

动态库是在程序运行起来的时候才去链接动态库的代码多个程序可以共享使用库的代码。它以.so结尾。

动态函数库共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.sowindows上叫动态加载函数库, 文件后缀是.dll

3.Linux中命名系统中共享库的规则

在这里插入图片描述

二.动态库和静态库的优缺点及区别

1.静态库的优点及缺点

优点:

  • 可移植性较强,一旦可执行程序编译成功不需要依赖静态库

缺点:

  • 每一份程序都需要将静态库的代码链接进去,生成的可执行程序较大浪费空间

2.动态库的优点及缺点

优点:

  • 在程序运行起来,才链接库,生成的可执行代码较小节约内存
  • 可以被多个程序共享(虚拟内存机制)

缺点:

  • 可移植性差。一旦库丢失了,所有用到它的程序都会崩溃

3.区别

  • 它们都是对二进制文件(.o)进行打包
  • 动态链接的可执行文件只需要包含函数入口地址的一个表,而静态链接需要外部函数的所有机器码
  • 动态库可以被多个进程共享(采用虚拟内存机制),而静态库不行

三.生成并使用静态库和动态库

1.生成静态库

以下边的一个简单例子来生成静态库:

//sum.h
#ifndef __SUM_H__
#define __SUM_H__

int sum(int x,int y);

#endif
//sub.h
#ifndef __SUB_H__
#define __SUB_H__

int sub(int x,int y);

#endif
//sum.c
#include "sum.h"
int sum(int x,int y)
{
   return x+y;
}
//sub.c
#include "sub.h"
int sub(int x,int y)
{
   return x-y;
}
//main.c
#include<stdio.h>
#include"sum.h"
#include"sub.h"

int main()
{
 printf("10+20=%d\n", sum(10,20));
 printf("10-20=%d\n", sub(10,20)); 
}
  • 第一步,我们写好如下程序
    在这里插入图片描述

  • 第二步,生成二进制文件(.o)
    gcc -c sum.c -o sum.o(只用编译器和汇编器,不用连接)
    在这里插入图片描述

  • 第三步,将.o文件通过ar工具打包成静态库
    ar -rc libmymath.a sub.o sum.o(-r:打包,-c:创建)
    在这里插入图片描述

  • 第四步,查看静态库中的目录文件
    ar -tv libmymath.a(-t:列出静态库中的文件,-v:详细信息)
    在这里插入图片描述

  • 第五步,使用静态库
    gcc main.c -L. -lmymath(-L:指定库路径,-l:指定库名,把lib和后缀删掉)
    在这里插入图片描述

实际使用中,我们会把头文件和静态库给别人,防止源代码泄露。我们可以新建一个文件夹,结构如下。lib下放的是静态库,而include下放的头文件
在这里插入图片描述

在使用时,只需要加上-I + 头文件所在的路劲即可编译成功。
gcc main.c -L ./staticlib/lib -lmymath -I ./staticlib/include
在这里插入图片描述

对于库搜索路径可以有三种方式:

  • -L指定库目录路径
  • 用环境变量LIBRARY_PATH指定库目录路径
  • 把库放入系统指定搜索目录/uer/lib

Makefile可以这么写:

libmymath.a:sub.o sum.o                               
  ar -rc libmymath.a sub.o sum.o                                                                                                   
sub.o:sub.c                                                       
  gcc -c sub.c -o sub.o                                                                               
sum.o:sum.c                                                            
  gcc -c sum.c -o sum.o                                                              
.PHONY:clean                                                      
clean:                                                            
  rm -rf sub.o sum.o

2.生成动态库

依然以静态库中的代码为例子:

  • 第一步,编写以下代码:
    在这里插入图片描述

  • 第二步,编译生成二进制文件(.o)
    gcc -fPIC -c sub.c sum.c,-fPIC参数会产生与位置无关代码,.so要求PIC码已达到动态链接的目的,否则,无法实现动态链接
    在这里插入图片描述

  • 第三步,生成动态库
    gcc -shared -o libmymath.so *.o,加上-shared参数表示生成共享库的格式
    在这里插入图片描述

  • 第四步,使用动态库

编译选项:-l:代表链接动态库,只要去掉lib和后缀即可-L:链接库所在的路径

gcc -L. -lmymath main.c
在这里插入图片描述

要想运行动态库,可以直接加上-L选项,后边加上链接库所在的路径即可。也可以通过以下两种方法:

  • 把动态库拷贝到系统默认搜索路径,usr/lib
  • 把动态库的路径加入到环境变量LD_LIBRARY_PATH
    在这里插入图片描述
    同样,我们也可以把头文件和库放在一个目录中,供别人使用,防止源码泄露:
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hansionz/article/details/83241499
今日推荐