动态库/静态库的动态加载和静态加载(Linux环境)

一、动态库的静态加载

1.编译动态库->链接成共享库

gcc -fpic -c math.c  -o math.o            //自行编写他们的头文件放在同一目录下
gcc -fpic -c show.c -o show.o
gcc -shared math.o show.o -o libmath.so   //libmath.so为动态库,libxxx其中 xxx 为动态库的名字

2.将动态库的路径加到环境变量中

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.     //.表示当前目录

3.生成可执行程序并运行

gcc main.c libmath.so -o math              //生成math,运行./math 
或
gcc main.c -L./ -lmath -o math

二、动态库的动态加载

动态加载是在程序运行期间加载和卸载动态库。Linux中的dl库实现库的动态加载。最终链接时,使用-ldl

#include <dlfcn.h>
void *dlopen(const char *filename,int flag);
char *dlerror(void);
void *dlsym(void *handle,const char *symbol);
int   dlclose(void *handle);

Link with -ldl

1.加载共享库---dlopen

void *dlopen(const char *filename,int flag);
--filename:如果有路径,按照路径加载;只有文件名时,根据LD_LIBRARY_PATH环境变量去查找
--flag:加载标志(RTLD_LAZY:延迟加载,什么时候真正使用,什么时候加载;RTLD_NOW:立即加载)
--返回值:成功返回动态库的句柄,失败返回NULL

2.获取动态库的函数地址---dlsym

void *dlsym(void *handle,const char *symbol);
--handle:动态库的句柄
--symbol:函数名
--返回值:成功返回函数地址,失败返回NULL

3.卸载动态库---dlclose

int dlclose(void *handle);
--handle:动态库句柄

4.获取出错信息--dlerror

char *dlerror(void);
--返回值:返回错误字符串

例子:

#include<stdio.h>
#include<dlfcn.h>
 
typedef int(*PFUNC_CALL)(int,int);
typedef int(*PFUNC_SHOW)(int);        //给函数指针定义一个别名   PFUNC_SHOW = int(*)(int)
 
int main()
{
 
    void *handle = dlopen("./libmath.so",RTLD_LAZY);  //加载动态库
        if(handle==NULL)
        {
            printf("dlopen失败:%s\n",dlerror());
            return -1;
        }
    //获取函数地址
    PFUNC_CALL add = (PFUNC_CALL)dlsym(handle,"add");
    if(add==NULL)
    {
        printf("dlsym失败:%s\n",dlerror());
        return -1;
    }
 
 
    int(*show)(int)= dlsym(handle,"show");              //int(*show)(int) = PFUNC_SHOW
    if(add==NULL)                                       // 函数原型  int show(int)
    {
        printf("dlsym失败:%s\n",dlerror());
        return -1;
    }
 
    show(add(9,5));
 
    dlclose(handle);
    return 0;
}

编译链接:

gcc dmain.c -ldl -o math

三、静态库

1.编译静态库

gcc math.cpp -c  //生成math.o
ar rc math.a math.o  //生成math.a

2.链接静态库

gcc main.cpp math.a -o main

 

总结:

动态加载都需要在代码中进行加载(编译脚本不需要);静态加载都是在编译脚本中进行加载(代码中不需要)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值