• Java Native Interface(JNI)


    JNI能让Java代码在Java虚拟机里调用其他编程语言(例如C、C++)写的应用或库,且不会影响任何Java虚拟机的实现。

    什么时候用JNI?

    1、应用程序所需的平台相关功能,标准的Java类库不支持时。

    2、已经有一个用其他语言写的库,想要复用时。

    3、想使用一些低级别的语言(例如汇编)实现部分关键代码时。

    JNI问题

    1、对开发者的要求更高。

    2、丧失可移植性。

    例子(C语言,on Mac)

    1、添加声明为native的方法。

    package nativetest;
    
    public class CaculatorInC {
    
        //加法
        public static native int add(int a, int b);
    }

    2、编译成h文件

    有包名,直接这样就可以编译成h文件。(不然会报找不到类文件)

    javah nativetest.CaculatorInC

    没包名,先编译成class

    javac xxx.java
    javah xxx

    生成的h文件内容

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class nativetest_CaculatorInC */
    
    #ifndef _Included_nativetest_CaculatorInC
    #define _Included_nativetest_CaculatorInC
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     nativetest_CaculatorInC
     * Method:    add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_nativetest_CaculatorInC_add
      (JNIEnv *, jclass, jint, jint);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    View Code

    3、编写自己c文件

    可以查看生成后的h文件,实现里面的方法。

    #include "jni.h"
    #include "nativetest_CaculatorInC.h"
     
    //#include otherheaders
     
    JNIEXPORT jint JNICALL Java_nativetest_CaculatorInC_add
    (JNIEnv *env, jclass object, jint a, jint b){
        return a + b;
    }

    4、将c文件编译成动态链接库

    gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/include/ *.c -o libcaculator.jnilib

    注意可能会报,jni.h或jni_md.h文件不存在。

    处理方法:

    1、找到jdk的位置(/usr/libexec/java_home -V),编译命令带上“xxx/Contents/Home/include”的目录,如上。

    2、把“xxx/Contents/Home/include/darwin”的目录里jni_md.h文件复制到include目录。

    5、测试

    package nativetest;
    
    import nativetest.CaculatorInC;
    
    public class Test {
        static {
            //System.setProperty("java.library.path", ".");
            System.load("/Users/lufeng/Documents/project/java-workspace/java-demo/src/libcaculator.jnilib"); // 载入本地库
        }
    
        public static void main(String[] args) {
            System.out.println(CaculatorInC.add(1, 2));
        }
    }

    参考文献

    https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/intro.html#java_native_interface_overview

  • 相关阅读:
    java中的CAS
    浅谈尾递归
    LeetCode 第 222 场周赛
    LeetCode 第 216 场周赛
    C++代码整洁之道
    LeetCode 第 211 场周赛
    LeetCode 每日一题 51.N 皇后
    LeetCode 第 201 场周赛
    LeetCode 第 32 场双周赛
    [转]演讲实录丨DevOps之十倍速原则
  • 原文地址:https://www.cnblogs.com/lovesong/p/8906877.html
Copyright © 2020-2023  润新知