关于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_75\include –I D:\jdk1.7.0_75\include\win32 IntArray.c –o intarray.dll

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

g++ -Wl,--kill-at –shared –I D:\jdk1.7.0_75\include –I D:\jdk1.7.0_75\include\win32 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   }

转载于:https://www.cnblogs.com/benxintuzi/p/4593437.html

2 通过JNI混合使用Java和C++ ----- 访问数组相关推荐

  1. 【转】JNI(Java Native Interface)的简介

    因为刚刚接触android和java平台,对JNI到底是什么,还不是很了解,所以从CSDN转载了一篇文章,以便自己对JNI有一个认识,也跟大家分享一下. JNI是Java Native Interfa ...

  2. Android JNI(Java Native Interface)技术介绍

    Android平台上的JNI技术介绍 JUL 15TH, 2013 | COMMENTS NDK简介 Android是由Google领导开发的操作系统,Android依靠其开放性,迅速普及,成为目前最 ...

  3. 本地方法(JNI)——访问数组元素+错误处理

    [0]README 1) 本文文字描述 均转自 core java volume 2 , 旨在理解 本地方法(JNI)--访问数组元素+错误处理 的基础知识 : 2)for source code, ...

  4. jni c java互相调用_通过JNI实现Java和C++的相互调用

    评论 # re: 通过JNI实现Java和C++的相互调用 2008-07-29 14:14 Always BaNg. 不错,把字符转换也一并讲了吧,比如UTF-8的处理,USC-2与MBCS转换等. ...

  5. android jni java调用c,Android与JNI(一) ---- Java调用C 静态调用

    第一.通过eclipse新建一个工程名为HelloJni的android工程,并编译. 第二.右键工程-->Android Tools --> Add Native Support,出现如 ...

  6. android jni 调用java对象_Android NDK开发之Jni调用Java对象

    本地代码中使用Java对象 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函 ...

  7. android jni与java之间数据传输时怎么转换

    1.c中的jstring数据类型就是java传入的String对象,经过jni函数的转化就能成为c的char*. Java 类型 本地c类型 说明 boolean jboolean 无符号 8 位 b ...

  8. jni java c 变量对应_GitHub - jkangzhang/JNIDemo: JNI中Java和C的数据传递

    基本类型 对于基本类型的传递,只需要按照表格找到对应即可. Java Type Native Type Description boolean jboolean 8 bits, unsigned by ...

  9. jni开发-java调用c函数,c调用java函数实现

    1.配置 下载ndk,cmake即可. 2.实现 MainActivity的实现 public class MainActivity extends AppCompatActivity {// Use ...

最新文章

  1. Swagger3.0 天天刷屏,真的香吗?
  2. SQL语句复习【专题八】
  3. [Yii Framework] Yii如何实现前后台的session分离
  4. java 中的vector_详解Java中的Vector
  5. 8、Python MySQL - mysql-connector 驱动
  6. [转]Design Pattern Interview Questions - Part 2
  7. 8、java中的内部类
  8. thinkphp index.php隐藏,thinkphp5怎么隐藏index.php入口文件?
  9. 线性代数:矩阵学习笔记
  10. Spring.Net学习笔记(3)-创建对象
  11. 如何设计 user 表?加入第三方登录呢?
  12. IOS 蓝牙开发(六)蓝牙手柄 GameController开发
  13. mysql触发器检验有效性_mysql触发器实例 两个触发器保证数据有效性
  14. UML基础(八)--构件图
  15. 怎样实现WhatsApp多开?
  16. 关于使用火车采集器采集分页URL不变化网站
  17. 钱多多的编程语言晋升路
  18. 周志华《机器学习》习题6.2
  19. AS608光学指纹模组编程和应用详解
  20. Godot中的GIProbe和Baked lightmaps

热门文章

  1. javascript - 全局与局部作用域
  2. 年报系统课堂讨论记录
  3. MySQL5.7.12新密码登录方式及密码策略
  4. php 会话控制 文件上传
  5. html页面头部里的meta
  6. 《Sibelius 脚本程序设计》连载(三十四) - 4.4 DateTime
  7. OpenCV 绘制几何图形
  8. Mybatis框架实现简单的学生管理系统
  9. Python用requests完成最简单的爬虫
  10. Altair Compose 2020直装中文版