JNI之c/c++混合调用

手写编译太麻烦了,推荐下载IntelliJ IDEA来写java

JNI的c/c++混合调用

  1. Main.java文件

    package com.zero_waring.jni_test;
    
    public class Main {
        static {
            System.loadLibrary("hello"); //  libhello.so
        }
        private native void sayHello();
        public static void main(String[] args) {
    	// write your code here
            new Main().sayHello();
        }
    }
    
  2. 生成对应.h

    javah -classpath ~/IdeaProjects/JniTest/src com.zero_waring.jni_test.Main

    //在Main.java同级目录下出现对应.h

  3. 编写JNICppImpl.h文件

    #ifndef _JNI_CPP_IMPL_
    #define _JNI_CPP_IMPL_
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void sayHello();
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    因为要被c调用所以使用extern c

  4. 编写JNICppImpl.cpp文件

    #include <iostream>
    #include "JNICppImpl.h"
    
    void sayHello() {
        std::cout << "this is jni" << std::endl;
    }
    
  5. 编译要被java侧调用的com_zero_waring_jni_test_Main.c

    #include <jni.h>
    #include "com_zero_waring_jni_test_Main.h"
    #include "JNICppImpl.h"
    
    JNIEXPORT void JNICALL Java_com_zero_1waring_jni_1test_Main_sayHello (JNIEnv *env, jobject thisObj) {
        sayHello();  // invoke C++ function
        return;
    }
    
  6. 编译生成so

    g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I ./ -shared com_zero_waring_jni_test_Main.c JNICppImpl.cpp  -o libhello.so
    
  7. 添加so 库

    export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

    可以看到当前目录下生成libhello.so

  8. 添加对应lib文件到java路径
    JVM的java.library.path属性即为环境变量Path指定的目录

    因为编译我们依赖了IntelliJ IDEA,所以要添加对应动态库路径

    点击run,点击Edit Configurations

    选中Main

    然后在 VM opition中添加

    -Djava.library.path=/home/chao/IdeaProjects/JniTest/src/com/zero_waring/jni_test

    然后编译就OK了

posted @ 2021-01-10 17:42  make_wheels  阅读(411)  评论(0编辑  收藏  举报