JNISystem.loadLibrary()原理

其实其内部最核心的原理是在c语言,而不是在java,其是利用了一个c语言的动态链接库来实现了加载动态链接库

dlopen、dlsym、dlclose加载动态链接库

我们先生成一个动态链接库

// lib.h
int gcd(int a,int b);

// lib.c
#include<lib.h>
int gcd(int a,int b){
        if(b == 0){
                return a;
        }
        return gcd(b,a%b);
}

用上面的函数生成动态链接库

# 生成动态链接库
gcc lib.c -fPIC -shared -o libl.so

使用上面的动态链接库

// t.c
#include<stdio.h>
// 三个函数所在头文件
#include<dlfcn.h>
// 函数指针
typedef int (*Gcd)(int,int);
int main(){
		// 加载对应的动态链接库,传入文件路径
        void* handle = dlopen("./libl.so",RTLD_LAZY);
        if(!handle){
                printf("dynamic link library load fail\n");
                return 0;
        }
        // 调用动态链接库中的函数
        Gcd gcd = (Gcd)dlsym(handle,"gcd");
        printf("gcd:%d\n",gcd(100,50));
        dlclose(handle);
}

编译

# 编译时候要加入 -ldl (指定dl库)
gcc t.c -ldl

之后就可以运行了

dlopen中的几个mode
RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。
RTLD_NOW:与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为 : undefined symbol: xxxx…
RTLD_GLOBAL:它的含义是使得库中的解析的定义变量在随后的其它的链接库中变得可以使用。
RTLD_LOCAL:与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其它库重定位。如果没有指明是RTLD_GLOBAL还是RTLD_LOCAL,则缺省为RTLD_LOCAL。

上述几种mode使用|进行组合

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值