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_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++ ----- 访问数组相关推荐
- 【转】JNI(Java Native Interface)的简介
因为刚刚接触android和java平台,对JNI到底是什么,还不是很了解,所以从CSDN转载了一篇文章,以便自己对JNI有一个认识,也跟大家分享一下. JNI是Java Native Interfa ...
- Android JNI(Java Native Interface)技术介绍
Android平台上的JNI技术介绍 JUL 15TH, 2013 | COMMENTS NDK简介 Android是由Google领导开发的操作系统,Android依靠其开放性,迅速普及,成为目前最 ...
- 本地方法(JNI)——访问数组元素+错误处理
[0]README 1) 本文文字描述 均转自 core java volume 2 , 旨在理解 本地方法(JNI)--访问数组元素+错误处理 的基础知识 : 2)for source code, ...
- jni c java互相调用_通过JNI实现Java和C++的相互调用
评论 # re: 通过JNI实现Java和C++的相互调用 2008-07-29 14:14 Always BaNg. 不错,把字符转换也一并讲了吧,比如UTF-8的处理,USC-2与MBCS转换等. ...
- android jni java调用c,Android与JNI(一) ---- Java调用C 静态调用
第一.通过eclipse新建一个工程名为HelloJni的android工程,并编译. 第二.右键工程-->Android Tools --> Add Native Support,出现如 ...
- android jni 调用java对象_Android NDK开发之Jni调用Java对象
本地代码中使用Java对象 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函 ...
- android jni与java之间数据传输时怎么转换
1.c中的jstring数据类型就是java传入的String对象,经过jni函数的转化就能成为c的char*. Java 类型 本地c类型 说明 boolean jboolean 无符号 8 位 b ...
- jni java c 变量对应_GitHub - jkangzhang/JNIDemo: JNI中Java和C的数据传递
基本类型 对于基本类型的传递,只需要按照表格找到对应即可. Java Type Native Type Description boolean jboolean 8 bits, unsigned by ...
- jni开发-java调用c函数,c调用java函数实现
1.配置 下载ndk,cmake即可. 2.实现 MainActivity的实现 public class MainActivity extends AppCompatActivity {// Use ...
最新文章
- Swagger3.0 天天刷屏,真的香吗?
- SQL语句复习【专题八】
- [Yii Framework] Yii如何实现前后台的session分离
- java 中的vector_详解Java中的Vector
- 8、Python MySQL - mysql-connector 驱动
- [转]Design Pattern Interview Questions - Part 2
- 8、java中的内部类
- thinkphp index.php隐藏,thinkphp5怎么隐藏index.php入口文件?
- 线性代数:矩阵学习笔记
- Spring.Net学习笔记(3)-创建对象
- 如何设计 user 表?加入第三方登录呢?
- IOS 蓝牙开发(六)蓝牙手柄 GameController开发
- mysql触发器检验有效性_mysql触发器实例 两个触发器保证数据有效性
- UML基础(八)--构件图
- 怎样实现WhatsApp多开?
- 关于使用火车采集器采集分页URL不变化网站
- 钱多多的编程语言晋升路
- 周志华《机器学习》习题6.2
- AS608光学指纹模组编程和应用详解
- Godot中的GIProbe和Baked lightmaps