静态库和动态库

静态库:将多个目标文件打包一个文件  扩展名 .a
里面是.o可执行文件

1:gcc -c clc.c show.c //生成执行文件.o

2:ar -r libmath.a clc.o show.o//加载到静态库中

ar [选项] 静态库文件.a  目标文件列表.o
-r   将目标插入到静态库中,已存在更新
-q  将目标文件追加到静态库尾
-d  从静态库中删除目标文件
-t   列表显示静态库中的目标文件
-x   将静态库展开为目标文件
库文件名:libmath.a
3:gcc main.c -lmain -L.. -o main//编译文件
-l:库文件名(去掉lib和.o) 
-L:库文件路径   通过环境变量设置路径LIBRARY_PATH=$LIBRARY_PATH:..

//计算模块头文件
#ifndef __CLC_H
#define __CLC_H
#include<stdio.h>
//加法函数
int add(int a,int b);
//减法函数
int sub(int a,int b);
#endif

//计算模块函数实现
#include"clc.h"
int add(int a,int b)
{
    return a+b;
}
int sub(int a,int b)
{
    return a-b;
}


//显示模块头文件
#ifndef __SHOW_H
#define __SHOW_H
#include<stdio.h>
void show(int , char, int, int);
#endif

//显示模块函数实现
#include"show.h"
void show(int x, char op, int y, int res)
{
    printf("%d %c %d = %d\n",x,op,y,res);
}


//接口文件
#ifndef __MATH_H
#define __MATH_H
#include"show.h"
#include"clc.h"
#endif


#include<stdio.h>
#include"math.h"
int main()
{
    int a = 123;
    int b = 456;
    show(a,'+',b,add(a,b));
    show(a,'-',b,sub(a,b));
    return 0;
}

动态库:扩展名 .so  s:share  o:object
gcc -c -fpic clc.c
gcc -c -fpic show.c
gcc -shared clc.o show.o -o libmath.so
gcc main.c libmath.so
./math
配置环境变量:LD_LIBRARY_PATH
PIC:位置无关码

动态库与静态库优缺点:

静态库:体积大,执行速度快,不依赖库的存在,不易于维护
动态库:体积小,执行速度慢,依赖库的存在,易于维护

动态库的动态加载

什么时候用什么时候加载,避免内存浪费。

#include<stdio.h>
//使用动态加载库文件需要包含此头文件
#include<dlfcn.h>

int main()
{
    //加载库libmath.so到内存 RTLD_LAZY:延时加载  RTLD_NOW:立即加载
    void *handel = dlopen("/home/tarena/UC/day02/shared/libmath.so",RTLD_NOW);
    if(handel ==NULL)
    {
        fprintf(stderr,"dlopen%s\n",dlerror());//stderr代表标准错误,
                                        //是一个文件,用fprintf输出到屏幕
        return -1;
    }
    //获取库函数地址
    int (*add)(int ,int) = dlsym(handel,"add");
    if(add == NULL)
    {
        fprintf(stderr,"dlsym:%s\n",dlerror());
        return -1;
    }
    int (*sub)(int ,int) = dlsym(handel,"sub");
    if(sub == NULL)
    {
        fprintf(stderr,"sub:%s\n",dlerror());
        return -1;
    }
    void (*show)(int,char,int,int) = dlsym(handel,"show");
    if(show ==NULL)
    {
        fprintf(stderr,"show:%s\n",dlerror());
        return -1;
    }
    //使用库
    int a = 123;
    int b = 456;
    show(a,'+',b,add(a,b));
    show(a,'-',b,sub(a,b));
    //卸载库
    if(dlclose(handel))
    {
        fprintf(stderr,"close:%s\n",dlerror());
    }
    return 0;
}

执行命令:gcc load.c -ldl

-ldl:-l代表库文件名   dl文件名

辅助工具:

查看符号表:nm(查看哪些是自己的函数,哪些是调用的函数等等、、、)

列出目标文件、可执行程序、静态库或共享库(动态库)中的符号

例如:nm libmath.a

查看依赖:ldd(查看文件需要哪些库)

查看可执行文件或者共享库多依赖的共享库

例如: ldd a.out

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值