• 2 通过JNI混合使用Java和C++ -----> 访问数组


    关于c和cpp实现native方法的一些注释:

    1>  在jni.h中首先定义了C的实现方式,然后用内联函数实现了Cpp的实现方式,如下所示:

    const char* GetStringUTFChars(jstring str, jboolean *isCopy)   /* 依赖于C方式实现Cpp */

    {

      return functions->GetStringUTFChars(this,str,isCopy);       /* C实现方式 */

    }

    因此,在C中可能这样写:(*env)->GetStringUTFChars(env, str, NULL); 但在CPP中,我们必须这么写:env->GetStringUTFChars(str, NULL);

    有两个主要区别:

    首先 ---> cpp函数不包含参数JNIEnv* env;

    其次 ---> 在cpp实现中,env直接指向包含JNI函数指针的函数表,而在c实现中,env只是指向某个位置,而该位置才包含一个指向函数表的指针,因此必须使用(*env)才能调用JNI函数。

    /* jni.h中JNIEnv的定义 */

    #ifdef __cplusplus

    typedef JNIEnv_ JNIEnv;                                 /* cpp定义 */

    #else

    typedef const struct JNINativeInterface_ *JNIEnv;       /* c定义 */

    #endif

     

    2>  关于动态库的编译:

    如果使用.c文件生成动态库,则使用gcc编译:

    gcc -Wl,--kill-at –shared –I D:jdk1.7.0_75include –I D:jdk1.7.0_75includewin32 IntArray.c –o intarray.dll

    如果使用.cpp文件生成动态库,则使用g++编译:

    g++ -Wl,--kill-at –shared –I D:jdk1.7.0_75include –I D:jdk1.7.0_75includewin32 ObjectArrayTest.cpp –o objectarraytest.dll

    JNI访问基本数组时与访问字符串类似,而且可以通过JNI函数SetIntArrayRegion改变基本数组的值。此外,JNI提供了一系列的Get/Release<Type>ArrayElements函数来操作基本数组,其返回/释放一个指向(元素本身或其副本)的指针,具体实现由JVM决定,比较安全,如下程序通过native方法计算int型数组的和:

     1 // IntArray.java
     2 class IntArray
     3 {
     4     static
     5     {
     6         System.loadLibrary("intarray");
     7     }
     8     private native int SumArray(int[] arr);
     9     
    10     public static void main(String[] args)
    11     {
    12         IntArray p = new IntArray();
    13         int arr[] = new int[10];
    14         for(int i = 0; i < 10; i++)
    15         {
    16             arr[i] = i;
    17         }
    18         int sum = p.SumArray(arr);
    19         System.out.println("sum = " + sum);
    20     }
    21 }
    22 
    23 /***********************************************/
    24 // Intarray.h
    25 /* DO NOT EDIT THIS FILE - it is machine generated */
    26 #include <jni.h>
    27 /* Header for class IntArray */
    28 
    29 #ifndef _Included_IntArray
    30 #define _Included_IntArray
    31 #ifdef __cplusplus
    32 extern "C" {
    33 #endif
    34 /*
    35  * Class:     IntArray
    36  * Method:    SumArray
    37  * Signature: ([I)I
    38  */
    39 JNIEXPORT jint JNICALL Java_IntArray_SumArray
    40   (JNIEnv *, jobject, jintArray);
    41 
    42 #ifdef __cplusplus
    43 }
    44 #endif
    45 #endif
    46 
    47 /***********************************************/
    48 // IntArray.c
    49 #include "IntArray.h"
    50 
    51 JNIEXPORT jint JNICALL Java_IntArray_SumArray
    52   (JNIEnv *env, jobject obj, jintArray arr)
    53   {
    54       jint buf[10];
    55       jint i, sum = 0;
    56       (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);
    57       for(i = 0; i < 10; i++)
    58       {
    59           sum += buf[i];
    60       }
    61       return sum;
    62   }

    JNI访问对象数组时使用函数对:Get/SetObjectArrayElement返回/更新指定索引的对象,如下native方法返回一个5*5的二维数组:

     1 //ObjectArrayTest.java
     2 class ObjectArrayTest
     3 {
     4     static
     5     {
     6         System.loadLibrary("objectarraytest");
     7     }
     8     private static native int[][] InitInt2DArray(int size);
     9     
    10     public static void main(String[] args)
    11     {
    12         int[][] int2DArr = InitInt2DArray(5);
    13         for(int i = 0; i < 5; i++)
    14         {
    15             for(int j = 0; j < 5; j++)
    16             {
    17                 System.out.println(int2DArr + "  ");
    18             }
    19             System.out.println();
    20         }        
    21     }
    22 }
    23 
    24 /***********************************************/
    25 // ObjectArrayTest.h
    26 class ObjectArrayTest
    27 {
    28     static
    29     {
    30         System.loadLibrary("objectarraytest");
    31     }
    32     private static native int[][] InitInt2DArray(int size);
    33     
    34     public static void main(String[] args)
    35     {
    36         int[][] int2DArr = InitInt2DArray(5);
    37         for(int i = 0; i < 5; i++)
    38         {
    39             for(int j = 0; j < 5; j++)
    40             {
    41                 System.out.println(int2DArr + "  ");
    42             }
    43             System.out.println();
    44         }        
    45     }
    46 }
    47 
    48 /***********************************************/
    49 // ObjectArrayTest.cpp
    50 #include "ObjectArrayTest.h"
    51 
    52 JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_InitInt2DArray
    53   (JNIEnv *env, jclass cls, jint size)
    54   {
    55       jobjectArray result;
    56       int i;
    57       jclass intArrCls = env->FindClass("[I");         /* "[I" 代表int[] */
    58       if(intArrCls == NULL)
    59       {
    60           return NULL;
    61       }
    62       result = env->NewObjectArray(size, intArrCls, NULL);  /* result是一个对象数组,其中的元素类型为int[] */
    63       if(result == NULL)
    64       {
    65           return NULL;
    66       }
    67       
    68       for(i = 0; i < size; i++)
    69       {
    70           jint temp[256];
    71           int j;
    72           jintArray intArr = env->NewIntArray(size);     /* 创建size个int元素的一维数组 */
    73           if(intArr = NULL)
    74           {
    75               return NULL;
    76           }
    77           for(j = 0; j < size; j++)
    78           {
    79               temp[j] = i + j;
    80           }
    81           env->SetIntArrayRegion(intArr, 0, size, temp);    /* 将temp中的内容复制到intArr中 */
    82           env->SetObjectArrayElement(result, i, intArr);    /* 将intArr中的内容复制到result中以便返回 */
    83           env->DeleteLocalRef(intArr);
    84       }
    85       return result;
    86   }
  • 相关阅读:
    mysql 语句的查询过程解析
    postman 百度网盘下载 64位
    java 读取文内容(text,html)
    java把Word文件转成html的字符串返回出去
    spring boot 2.X上传文件限制大小
    nginx 做反向代理
    Linux下安装Redis
    微信小程序云开发个人博客项目实战(2)---引入-Vant-Weapp-小程序-UI-组件库
    微信小程序云开发个人博客项目实战(1)- 准备工作及引入 Vant Weapp 小程序 UI 组件库
    Video 视频播放防作弊和禁止下载
  • 原文地址:https://www.cnblogs.com/benxintuzi/p/4593437.html
Copyright © 2020-2023  润新知