Java使用JNI方法创建so文件,并且在linux系统下调用出现的问题及解决方案

1、前言

  • 这篇博客是关于如何使用Java的JNI技术完成so文件的创建,并且在linux系统下调用出现的一些坑和解决的办法

  • 主要是参考这篇博客:https://www.cnblogs.com/LiuYanYGZ/p/6109516.html

  • 主要遇到的坑:

    • Java文件中没有去掉包名,报了找不到的错误
    • .c文件中可以直接在里面写关于jni的函数代码,然后去调用上面的c程序函数就行
    • 报了undefined symbol的错,并且用ldd -r去查找了缺失的具体函数名,是sin,cos等基础的,最后在编译时加上-lm就行,主要参考这篇博客:https://bbs.csdn.net/topics/390290096

2、整体步骤

  • 需要准备的文件,.c文件,.java文件

2.1、.java文件

  • public class Hello {
        static {
            System.loadLibrary("goodluck");
        }
        public native double maxValue(String address);
    
        public static void main(String[] args) {
            Hello hello = new Hello();
            double res = hello.maxValue("/myprojects/mytest/data.txt");
            System.out.println(res);
        }
    }
    

    这里的路劲地址是传入的自己放在linux下的文件地址,写自己的就行

2.2、.c文件

  • #include <stdio.h>
    #include "jni.h"
    #include "math.h"
    ...
    ...
    // 中间是C语言代码
    ...
    ...
    jdouble Java_Hello_maxValue(JNIEnv* env, jobject obj, jstring address){
        char* add = (char*)(*env)->GetStringUTFChars(env, address, NULL);
        double res = maxValue(add);	// 调用上面的C语言代码的函数
        (*env)->ReleaseStringUTFChars(env, address, add);
        return res;
    }
    
  • 这里就是直接调用上面C语言代码中关于maxValue的函数,注意类型转换就好,具体的类型转换参考下面这篇博客:https://xuexiangjys.blog.csdn.net/article/details/83115117,注意函数名和参数返回值就行,实在不会的可以找找其他关于这方面的资料或者私信我,我也不是很懂,看缘分解决。

2.3、操作(在linux系统下)

  • 我用的Xshell和Xftp

  • 将这两个文件丢掉一个文件夹下,如果之前java文件里面有package xxx的话要创建对应的文件夹,不然的话删掉也行

  • 依次运行如下命令

    • javah Hello	# Hello是.java文件的名字,也就是类名,这里是生成头文件
      
      
      javac Hello.java # 这里是编译生成class文件
      
      
      gcc -lm -fpic -D_REENTRANT -I /environments/java/jdk1.8.0_311/include/ -I /environments/java/jdk1.8.0_311/include/linux/ -c Hello.c -std=c99 # 这里是调用自己安装的java路径下的头文件,编译生成.o文件,注意要加-lm,这里我也不清楚加不加,但加了是不报错的,这里std=c99是c语言代码中的问题,会报一个c99mode的错误,加上这个就好了
      
      
      gcc -lm -shared Hello.o -o libgoodluck.so # 这里是生成.so文件,注意要lib打头,并且后面的名字是上面System.loadLibrary里面的名字,注意加-lm,加了不报错
      
      
      export LD_LIBRARY_PATH=. # 这里是让自己的so文件能找到,不然会报下面的错
      

      在这里插入图片描述

      这里应该有永久性的方法,具体的去搜搜,我这里就简单处理一下了

    • java Hello # 运行,调用Hello里面的main方法
      

3、undefined symbol的问题

  • 问题还原:

    在这里插入图片描述

  • 解决方案:就是我上面操作步骤中在gcc编译的时候加上-lm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值