JNI

作者: 大龄程序员在帝都 | 来源:发表于2017-03-30 15:30 被阅读41次

    **
    需求: 需要通过Java调用C++代码完成对应的操作
    **

    简单说下方法:
    1、首先定义对应的执行类和在类中声明native方法
    目前只测试了传入int类型值 的方法调用,其他应该是一样的

    public class RecorderHandler {
        public native int intMethod(int n);
        public native boolean booleanMethod(boolean bool);
        public native String stringMethod(String text);
        public native int intArrayMethod(int[] intArray);
        
        public static void main(String[] args) {
            System.loadLibrary("RecorderHandler");
            RecorderHandler recorderHandler = new RecorderHandler();
            int i = recorderHandler.intMethod(9);
            // boolean bool = recorderHandler.booleanMethod(true);
            // String text = recorderHandler.stringMethod("Java");
            // int  sum = recorderHandler.intArrayMethod(new int[]{1,2,3});
            
            System.out.println("intMethod: " + i);
        //  System.out.println("booleanMethod: " + bool);
        //  System.out.println("stringMethod: " + text);
        //  System.out.println("intArrayMethod: " +sum);
        // }
        }
        
    }
    

    2、编译生成对应的class文件:

    javac RecorderHandler.java
    生成对应的class类
    

    3、调用javah命令生成对应的头文件,这个头文件就是需要用C++代码实现的头文件

    javah RecorderHandler
    

    生成头文件如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class RecorderHandler */
    
    #ifndef _Included_RecorderHandler
    #define _Included_RecorderHandler
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     RecorderHandler
     * Method:    intMethod
     * Signature: (I)I
     */
    JNIEXPORT jint JNICALL Java_RecorderHandler_intMethod
      (JNIEnv *, jobject, jint);
    
    /*
     * Class:     RecorderHandler
     * Method:    booleanMethod
     * Signature: (Z)Z
     */
    JNIEXPORT jboolean JNICALL Java_RecorderHandler_booleanMethod
      (JNIEnv *, jobject, jboolean);
    
    /*
     * Class:     RecorderHandler
     * Method:    stringMethod
     * Signature: (Ljava/lang/String;)Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_RecorderHandler_stringMethod
      (JNIEnv *, jobject, jstring);
    
    /*
     * Class:     RecorderHandler
     * Method:    intArrayMethod
     * Signature: ([I)I
     */
    JNIEXPORT jint JNICALL Java_RecorderHandler_intArrayMethod
      (JNIEnv *, jobject, jintArray);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    
    

    4、对头文件进行实现,c++部分实现

    #include "RecorderHandler.h"
    #include <string.h>
    #include<stdio.h>
    #include<stdlib.h>
    JNIEXPORT jint JNICALL Java_RecorderHandler_intMethod
      (JNIEnv *env, jobject obj, jint num)
    {
        return num * num;
    }
    
    JNIEXPORT jboolean JNICALL Java_RecorderHandler_booleanMethod
      (JNIEnv *env, jobject obj, jboolean boolean)
    {
        return !boolean;
    }
    
    JNIEXPORT jstring JNICALL Java_RecorderHandler_stringMethod
      (JNIEnv *env, jobject obj, jstring string)
    {
        const char* str = env->GetStringUTFChars(string, 0);
        char cap[128];
        strcpy(cap, str);
        env->ReleaseStringUTFChars(string, 0);
        //return env->NewStringUTF(strdup(cap));
        return NULL;
    }
    
    JNIEXPORT jint JNICALL Java_RecorderHandler_intArrayMethod
      (JNIEnv *env, jobject obj, jintArray array)
    {
        int i, sum = 0;
        jsize len = env->GetArrayLength(array);
        jint *body = env->GetIntArrayElements(array, 0);
    
        for (i = 0; i < len; ++i)
        {
            sum += body[i];
        }
        env->ReleaseIntArrayElements(array, body, 0);
        return sum;
    }
    
    

    5、对以上文件进行编译:如何编译并且进行链接是最重要的一步
    注意: -I是对应的链接库库,文件结尾应该是dylib,因为我的mac系统,mac下面的结尾文件应该是dylib,如果是windows应该是.ddl文件吧,如果是linux上进行编译,应该是.so文件吧

    g++ -shared -I /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/include  -I/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/include/darwin -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include RecorderHandler.cpp -o libRecorderHandler.dylib
    

    执行完了以后,就会在对应的目录生成:

    Paste_Image.png

    然后进行执行:因为我编译的时候intMethod传入的是9,又因为是去做乘法,所以 9*9输出结果为81
    java RecorderHanlder

    Paste_Image.png

    mac版本JNI参考
    一般参考
    Java调用jni绝对路径
    jni调用的一些列参考,非常详细,重点看

    相关文章

      网友评论

          本文标题:JNI

          本文链接:https://www.haomeiwen.com/subject/xkqpottx.html