java调用本地方法--JNI访问List集合

本篇结构:

  • 简介
  • 实例

一、简介

因为对C/C++不算了解,所以JNI系列的博文更多是在实战操作方面,这里接上面的文章,补充下JNI访问List集合实例。

二、实例

2.1、编写java类

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: w1992wishes
 * @Date: 2018/5/12 10:44
 */
public class JNIListTest {

    static {
        System.loadLibrary("JNIListTest");
    }

    private native void execute(List<float[]> points);

    public static void main(String[] args) {
        List<float[]> points = new ArrayList<>();
        points.add(new float[]{0.1f, 0.2f, 0.3f});
        points.add(new float[]{0.4f, 0.5f, 0.6f});
        points.add(new float[]{0.7f, 0.8f, 0.9f});

        JNIListTest test = new JNIListTest();
        test.execute(points);
    }
}

2.2、编译java类

javac JNIListTest.java

2.3、生成相关JNI方法的头文件

javah -d jnilib -jni JNIListTest

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIListTest */

#ifndef _Included_JNIListTest
#define _Included_JNIListTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIListTest
 * Method:    execute
 * Signature: (Ljava/util/List;)V
 */
JNIEXPORT void JNICALL Java_JNIListTest_execute
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

2.4、使用C/C++实现本地方法

#include "JNIListTest.h"
#include <stdio.h>

extern "C"
JNIEXPORT void JNICALL Java_JNIListTest_execute
  (JNIEnv *env, jobject obj, jobject objectList)
{
    const char *str ="enter native method\n";
    printf("%s",str);

    /* get the list class */
    jclass cls_list = env->GetObjectClass(objectList);
    if(cls_list == NULL){
        printf("%s","not find class\n");
    }

    /* method in class List  */
    jmethodID list_get = env->GetMethodID(cls_list, "get", "(I)Ljava/lang/Object;");
    jmethodID list_size = env->GetMethodID(cls_list, "size", "()I");
    if(list_get == NULL){
        printf("%s","not find get method\n");
    }
    if(list_size == NULL){
        printf("%s","not find size method\n");
    }

    /* jni invoke list.get to get points count */
    int len = static_cast<int>(env->CallIntMethod(objectList, list_size));
    if(len > 0){
        printf("len %d\n", len);
    }

    /* Traversing all counts */
    int i;
    for (i=0; i < len; i++) {
        /* get list the element -- float[] */
        jfloatArray element = (jfloatArray)(env->CallObjectMethod(objectList, list_get, i));
        if(element == NULL){
            printf("%s","fetch list element failure\n");
        }

        float *f_arrays;
        f_arrays = env->GetFloatArrayElements(element,NULL);
        if(f_arrays == NULL){
            printf("%s","fetch float array failure\n");
        }

        int arr_len = static_cast<int>(env->GetArrayLength(element));
        int j;
        for(j=0; j<arr_len ; j++){
            printf("\%f \n", f_arrays[j]);
        }

       /* 释放可能复制的缓冲区 */
       env->ReleaseFloatArrayElements(element, f_arrays, 0);
       /* 调用 JNI 函数 DeleteLocalRef() 删除 Local reference。Local reference 表空间有限,这样可以避免 Local reference 表的内存溢出,避免 native memory 的 out of memory。*/
       env->DeleteLocalRef(element);
    }
}

2.5、生成动态链接库

g++ -D_REENTRANT -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libJNIListTest.so JNIListTest.cpp

2.6、运行java

最后运行java -Djava.library.path=jnilib JNIListTest。

猜你喜欢

转载自blog.csdn.net/w1992wishes/article/details/80289753