2 通过JNI混合使用Java和C++ -----> 访问数组
2015-06-22 16:21
666 查看
关于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型数组的和:
JNI访问对象数组时使用函数对:Get/SetObjectArrayElement返回/更新指定索引的对象,如下native方法返回一个5*5的二维数组:
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型数组的和:
// IntArray.java class IntArray { static { System.loadLibrary("intarray"); } private native int SumArray(int[] arr); public static void main(String[] args) { IntArray p = new IntArray(); int arr[] = new int[10]; for(int i = 0; i < 10; i++) { arr[i] = i; } int sum = p.SumArray(arr); System.out.println("sum = " + sum); } } /***********************************************/ // Intarray.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class IntArray */ #ifndef _Included_IntArray #define _Included_IntArray #ifdef __cplusplus extern "C" { #endif /* * Class: IntArray * Method: SumArray * Signature: ([I)I */ JNIEXPORT jint JNICALL Java_IntArray_SumArray (JNIEnv *, jobject, jintArray); #ifdef __cplusplus } #endif #endif /***********************************************/ // IntArray.c #include "IntArray.h" JNIEXPORT jint JNICALL Java_IntArray_SumArray (JNIEnv *env, jobject obj, jintArray arr) { jint buf[10]; jint i, sum = 0; (*env)->GetIntArrayRegion(env, arr, 0, 10, buf); for(i = 0; i < 10; i++) { sum += buf[i]; } return sum; }
JNI访问对象数组时使用函数对:Get/SetObjectArrayElement返回/更新指定索引的对象,如下native方法返回一个5*5的二维数组:
//ObjectArrayTest.java class ObjectArrayTest { static { System.loadLibrary("objectarraytest"); } private static native int[][] InitInt2DArray(int size); public static void main(String[] args) { int[][] int2DArr = InitInt2DArray(5); for(int i = 0; i < 5; i++) { for(int j = 0; j < 5; j++) { System.out.println(int2DArr + " "); } System.out.println(); } } } /***********************************************/ // ObjectArrayTest.h class ObjectArrayTest { static { System.loadLibrary("objectarraytest"); } private static native int[][] InitInt2DArray(int size); public static void main(String[] args) { int[][] int2DArr = InitInt2DArray(5); for(int i = 0; i < 5; i++) { for(int j = 0; j < 5; j++) { System.out.println(int2DArr + " "); } System.out.println(); } } } /***********************************************/ // ObjectArrayTest.cpp #include "ObjectArrayTest.h" JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_InitInt2DArray (JNIEnv *env, jclass cls, jint size) { jobjectArray result; int i; jclass intArrCls = env->FindClass("[I"); /* "[I" 代表int[] */ if(intArrCls == NULL) { return NULL; } result = env->NewObjectArray(size, intArrCls, NULL); /* result是一个对象数组,其中的元素类型为int[] */ if(result == NULL) { return NULL; } for(i = 0; i < size; i++) { jint temp[256]; int j; jintArray intArr = env->NewIntArray(size); /* 创建size个int元素的一维数组 */ if(intArr = NULL) { return NULL; } for(j = 0; j < size; j++) { temp[j] = i + j; } env->SetIntArrayRegion(intArr, 0, size, temp); /* 将temp中的内容复制到intArr中 */ env->SetObjectArrayElement(result, i, intArr); /* 将intArr中的内容复制到result中以便返回 */ env->DeleteLocalRef(intArr); } return result; }
相关文章推荐
- C++静态局部对象
- C语言源字符集与执行字符集
- 两个乒乓球队进行比赛,各出3人。
- 无向图 广度优先遍历 c语言实现
- C语言回顾(六、基类型,数组指针,字符串指针,函数指针,文字常量区)——iOS开发基础
- Eclipse+CDT+Cygwin进行C&C++开发
- C++中的C_str()函数用法
- 标准C++库中的异常类
- c++操作符重载
- vc++6.0错误
- C++ 复习
- C语言中的undefined behavior
- 2015-第14周项目4-处理C++源代码的程序
- C++数组的简单示例
- [LeetCode] Basic Calculator II
- [转]Visual C++ RunTime的特征——非烫即屯
- 学习C++编程时,遇到过的小问题
- C++学习笔记__类的派生和多态性
- C++程序设计--对象分册(第5章)
- C++中模板声明与实现的分离问题