• 一个JNI的Demo,linux上下载就可以用


    最近用到了Java,需要用Java调用c++做的.so,搜了一下,有一个demo,但是这个demo有严重的问题。 加载.so的时候不好好地用 System.loadLibrary("hello");

    他用System.load("hello");这个函数需要使用全路径。总是报这个错误:

    Expecting an absolute path of the library:

    真他么的。害人不浅。

    这里我就做个demo,直接拿去用,就可以知道整个流程了。

    如果不想太清楚也不要紧,用就行了。

    谴责一个这个出来害人的博主。

    JNI详解------完整Demo_java jni-CSDN博客

     

    一、环境准备

    ubuntu20.04

    装jdk, 用default-jdk就可以。默认装的是jdk11

    1. sudo apt install openjdk-11-jdk
    2. sudo apt install default-jdk
    1. $java -version
    2. openjdk version "11.0.20.1" 2023-08-24
    3. OpenJDK Runtime Environment (build 11.0.20.1+1-post-Ubuntu-0ubuntu120.04)
    4. OpenJDK 64-Bit Server VM (build 11.0.20.1+1-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)

    gcc g++ 这些就不用说了,肯定也要的。

    sudo apt install build-essential

    二、下载代码

    可以在这下载

    https://download.csdn.net/download/v6543210/88475296

    如果下载不了,就从下面的代码自己粘贴一下。

    压缩包中的文件内容如下:

    1. ├── build.sh
    2. ├── demo
    3. │   └── hello.java
    4. ├── demo_hello.cpp
    5. ├── demo_hello.h
    6. └── Main.java

     demo是文件夹

    demo/hello.java的内容

    1. package demo;
    2. public class hello {
    3. {
    4. // 加载.so
    5. //System.setProperty("java.library.path", "./");
    6. //System.load("/home/demo/work/java/libhello.so"); //不要使用load,load需要全路径
    7. System.loadLibrary("hello"); //load libhello.so
    8. }
    9. /**
    10. * 就这个natice关键字.标记了这个接口,看起来像是abstract
    11. */
    12. public native int sayHello(String msg);
    13. }

     demo_hello.cpp的内容:

    1. #include "demo_hello.h"
    2. #include
    3. #include
    4. JNIEXPORT int JNICALL Java_demo_hello_sayHello(JNIEnv *env, jobject obj, jstring inJNIStr){
    5. const char *inCStr = env->GetStringUTFChars(inJNIStr, NULL);
    6. if (NULL == inCStr) return 1;
    7. using namespace std;
    8. cout << "Hello World"<< endl;
    9. cout << inCStr << endl;
    10. return 0;
    11. }

    Main.java的内容:

    1. import demo.*;
    2. public class Main {
    3. public static void main(String[] args) {
    4. new demo.hello().sayHello("java");
    5. }
    6. }

    三、编译运行过程

    具体编译和运行的过程都写在build.sh中了,build.sh具体内容如下:

    1. export JAVA_HOME=/usr/lib/jvm/default-java
    2. javac -h . demo/hello.java
    3. g++ -fPIC -shared demo_hello.cpp -o libhello.so -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux"
    4. javac Main.java
    5. export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
    6. java -Djava.library.path=. Main

    现在的java 11里面没有javah这个命令了,取尔代之的是 javac -h命令

    JAVA_HOME就用这个/usr/lib/jvm/default-java就挺好,省得去查版本号。

    demo_hello.cpp这个文件的名字你可以自己定,demo_hello.h这个文件是 javac -h 命令生成的。

     

    ./build.sh运行后会在目录中生成libhello.so

    运行程序时指定 java.library.path为当前目录,可以直接从当前目录加载libhello.so

    java -Djava.library.path=. Main

    运行java程序就可以看到输出结果:

    1. jni$ ./build.sh
    2. Hello World
    3. java

  • 相关阅读:
    springboot+爱心捐赠小程序 毕业设计-附源码211711
    Mysql索引、事务与存储引擎 (索引)
    pyspark 检测任务输出目录是否空,避免读取报错
    清览题库--C语言程序设计第五版编程题解析(3)
    深度解读汽车域控制器
    LeetCode-1. Two Sum
    索引的数据结构、索引及其优缺点、索引的声明与使用以及索引的设计原则
    画图实战-Python实现某产品全年销量数据多种样式可视化
    JAVA-STUDY
    citrix 脚本使用
  • 原文地址:https://blog.csdn.net/v6543210/article/details/134051813