[关闭]
@w1992wishes 2018-05-12T11:13:07.000000Z 字数 2553 阅读 2514

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

JAVA_JNI


本篇结构:

一、简介

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

二、实例

2.1、编写java类

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /**
  4. * @Author: w1992wishes
  5. * @Date: 2018/5/12 10:44
  6. */
  7. public class JNIListTest {
  8. static {
  9. System.loadLibrary("JNIListTest");
  10. }
  11. private native void execute(List<float[]> points);
  12. public static void main(String[] args) {
  13. List<float[]> points = new ArrayList<>();
  14. points.add(new float[]{0.1f, 0.2f, 0.3f});
  15. points.add(new float[]{0.4f, 0.5f, 0.6f});
  16. points.add(new float[]{0.7f, 0.8f, 0.9f});
  17. JNIListTest test = new JNIListTest();
  18. test.execute(points);
  19. }
  20. }

2.2、编译java类

javac JNIListTest.java

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

javah -d jnilib -jni JNIListTest

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class JNIListTest */
  4. #ifndef _Included_JNIListTest
  5. #define _Included_JNIListTest
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class: JNIListTest
  11. * Method: execute
  12. * Signature: (Ljava/util/List;)V
  13. */
  14. JNIEXPORT void JNICALL Java_JNIListTest_execute
  15. (JNIEnv *, jobject, jobject);
  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif

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

  1. #include "JNIListTest.h"
  2. #include <stdio.h>
  3. extern "C"
  4. JNIEXPORT void JNICALL Java_JNIListTest_execute
  5. (JNIEnv *env, jobject obj, jobject objectList)
  6. {
  7. const char *str ="enter native method\n";
  8. printf("%s",str);
  9. /* get the list class */
  10. jclass cls_list = env->GetObjectClass(objectList);
  11. if(cls_list == NULL){
  12. printf("%s","not find class\n");
  13. }
  14. /* method in class List */
  15. jmethodID list_get = env->GetMethodID(cls_list, "get", "(I)Ljava/lang/Object;");
  16. jmethodID list_size = env->GetMethodID(cls_list, "size", "()I");
  17. if(list_get == NULL){
  18. printf("%s","not find get method\n");
  19. }
  20. if(list_size == NULL){
  21. printf("%s","not find size method\n");
  22. }
  23. /* jni invoke list.get to get points count */
  24. int len = static_cast<int>(env->CallIntMethod(objectList, list_size));
  25. if(len > 0){
  26. printf("len %d\n", len);
  27. }
  28. /* Traversing all counts */
  29. int i;
  30. for (i=0; i < len; i++) {
  31. /* get list the element -- float[] */
  32. jfloatArray element = (jfloatArray)(env->CallObjectMethod(objectList, list_get, i));
  33. if(element == NULL){
  34. printf("%s","fetch list element failure\n");
  35. }
  36. float *f_arrays;
  37. f_arrays = env->GetFloatArrayElements(element,NULL);
  38. if(f_arrays == NULL){
  39. printf("%s","fetch float array failure\n");
  40. }
  41. int arr_len = static_cast<int>(env->GetArrayLength(element));
  42. int j;
  43. for(j=0; j<arr_len ; j++){
  44. printf("\%f \n", f_arrays[j]);
  45. }
  46. /* 释放可能复制的缓冲区 */
  47. env->ReleaseFloatArrayElements(element, f_arrays, 0);
  48. /* 调用 JNI 函数 DeleteLocalRef() 删除 Local reference。Local reference 表空间有限,这样可以避免 Local reference 表的内存溢出,避免 native memory 的 out of memory。*/
  49. env->DeleteLocalRef(element);
  50. }
  51. }

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。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注