zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    多任务拷贝小案例
    进程池
    进程间的通信
    互斥锁
    创建函数/类的线程
    udp/tcp流程
    发布模块
    私有属性/方法的访问
    深入了解jQuery之整体架构
    (转)前端面试题
  • 原文地址:https://www.cnblogs.com/lovesong/p/8906877.html
Copyright © 2011-2022 走看看