使用JNI机制加载本地方法的小案例

JNI

最近在学习Android,其中需要使用到c的库,这个时候就要使用到JNI机制了,简单来说,就是可以通过这个机制,让java代码可以调用本地c语言编写的代码,将c语言编写的代码打包成动态库,然后,在java代码中使用native关键字修饰方法,再将so文件加载进JVM即可,那么废话不多说,下面来看看这个demo吧。

编写java程序

package com.bwzfy;

public class App {

    private native void print();

    public static void main(String[] args) {
        new App().print();
    }

    static {
        System.loadLibrary("App");
    }
}

这个java程序很简单吧,就是在App这个类加载之前,将动态库加载进到JVM内存中,注意了。System.loadLibrary("App");这行代码里面的App是动态库的名字,正常在linux中,动态库的名字是libxxx.so。如果我们的目标程序打包成动态库的话,那名字就是libApp.so。前面的lib和后缀.so都是固定死的,所以我们加载动态库的时候只需要写中间那部分就可以了。

使用javah命令编译出.h文件

首先使用javac命令,将上面的源代码编译成class文件

javac App.java

此时此刻,我们会在App.java这个文件的目录下看到App.class文件,这里有个坑,不建议把App.class文件和App.java文件放在一个目录下。浪费了我很多时间,可以参考https://blog.csdn.net/weixin_45414277/article/details/109364327。

我这里将App.class文件单独放置到了一个目录下。

然后这个时候使用javah命令将class文件编译成.h文件。

javah -jni -cp /opt/project/hightlight/classes com.bwzfy.App

我们可以在当前自己所在目录下看到这么一个文件

编写对应c文件

我这里就是这个hello.c文件代码如下:

#include <jni.h>
#include <stdio.h>
#include "com_bwzfy_App.h"

JNIEXPORT void JNICALL Java_com_bwzfy_App_print
  (JNIEnv *jni, jobject jo){
        printf("hello world 114514");
}

JNI的gcc编译c文件成动态库

随后我们需要将编写好的本地c程序打包成动态库的形式,命令如下(根据自己的实际情况作修改)。

gcc -I $JAVA_HOME/include/ -I $JAVA_HOME/include/linux/ hello.c -shared -fPIC -o libApp.so

java启动,并指定so路径

最后就可以启动java程序了,这里注意需要指定一下java程序从哪里获取这个动态库,可以在启动的时候使用-Djava.library.path来指定jvm从哪里加载动态库,我们只需要把刚才生成的动态库放置到这个目录下即可。

启动命令如下:

java -Djava.library.path=/opt/project/highlight/lib -cp ./classes com.bwzfy.App

运行结果:

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值