Linux程序设计(一)——静态库

静态库概述(度娘一波)

静态库,也称归档文件(archive),是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。

程序编译一般需经预处理、编译、汇编和链接几个步骤。静态库特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。

静态库(*.a)(这里的.a指的是)和动态库(*.)是两种共享程序代码的方式,它们的区别是:静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。

 

创建和使用静态库

编译过程一览

预处理   .i .ii文件     gcc -E hello.cpp -o hello.i

编译    .s文件     gcc -S hello.cpp -o hello.s

汇编    .o .obj文件       gcc -c hello.cpp -o hello.o

链接    .lib .a文件

假设我们现在有两个文件,main.cpp和func.cpp,main.cpp使用了func.cpp里面的函数,那么在汇编完成产生目标文件后,链接器会在链接时将两个文件链接成可执行文件(.out)文件。下面是例子

//main.c
#include<stdlib.h>
#include"lib.h" //头文件

int main()
{
    func("Hello World");  //声明在lib.h头文件里
    exit(0);
}
//头文件 lib.h
void func(char* );
//func.c
#include<stdio.h>
void func(char* a)
{
    printf("%s\n",a);
}

过程:

1. 使用gcc -c 生成目标文件

gcc -c main.c func.c

执行完会生成main.o和func.o目标文件

2. 接下来要链接成可执行文件

gcc -o proexec main.o func.o

这条命令会生成一个名为proexec的可执行文件,直接运行就可以看到输出“hello world”。

 

上面编译过程特地将链接过程单独分出来,是因为我们在使用静态库的时候,其实是在链接的时候和目标文件一起生成可执行文件的过程。假设我们又有一个文件,里面有其他我们没用上的函数

//otherfunc.c
#include<stdlio.h>

void otherfunc(int arg)
{
    printf("other func\n");
}

我们不希望使用其他函数的时候还得一个一个写命令,希望把他们打包到一个静态库文件里,后面使用到任何在这个库里面到函数,只需要加入这个库的路径就可以链接成可执行文件了,而不用gcc -o x.o y.o z.o这么麻烦。我们需要如下命令:

gcc -c other.c //编译成目标文件
ar crv lib.a other.o func.o //打包成静态库

执行完后,会生成静态库文件。

gcc -o proexec2 main.o lib.a

这时候就不用一个一个函数指定了,直接链接静态库,就会生成我们需要的可执行文件proexec2.

 

共享库和静态库的区别

静态库有一个缺点,当你同时运行多个程序并且他们都使用同一个函数库的函数时,内存就会有多个函数的副本,这会浪费大量的内存资源。而共享库可以解决这种问题。

当一个程序使用共享库时,它的链接方式是这样的:程序本身不包含函数代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存执行时,函数引用被解析并产生对共享库的调用,如果有必要,共享库才会被加载到内存中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值