JNI参数传递
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JNI参数传递
对于基本数据类型,在native层接⼝看到的参数,对应的都已经转换成native层的数据类型了,只是名字为了好对应,⽤ typedef 做了转换。
JAVA 的基本数据类型:
数据类型⼤⼩范围 默认值
byte(字节) 8 -128 - 127 0
shot(短整型) 16 -32768 - 32768 0
int(整型) 32 -2147483648-2147483648 0
long(长整型) 64 -9233372036854477808-9233372036854477808 0
float(浮点型) 32 -3.40292347E+38-3.40292347E+38 0.0f
double(双精度) 64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char(字符型) 16 ‘ \u0000 - u\ffff ’ ‘\u0000 ’
boolean(布尔型) 1 true/false false
JAVA 数据类型对应的JNI数据类型:
/* "cardinal indices and sizes" */
#ifdef HAVE_INTTYPES_H
# include <inttypes.h> /* C99 */
typedef uint8_t jboolean; /* unsigned 8 bits */
typedef int8_t jbyte; /* signed 8 bits */
typedef uint16_t jchar; /* unsigned 16 bits */
typedef int16_t jshort; /* signed 16 bits */
typedef int32_t jint; /* signed 32 bits */
typedef int64_t jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#else
typedef unsigned char jboolean; /* unsigned 8 bits */
typedef signed char jbyte; /* signed 8 bits */
typedef unsigned short jchar; /* unsigned 16 bits */
typedef short jshort; /* signed 16 bits */
typedef int jint; /* signed 32 bits */
typedef long long jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
typedef jint jsize;
Java的 String 和 JNI中的 JString 的关系:
#ifdef __cplusplus
/*
* Reference types, in C++
*/
class _jobject {};
class _jstring : public _jobject {};
typedef _jobject* jobject;
typedef _jstring* jstring;
#else
/* not __cplusplus */
typedef void* jobject;
typedef jobject jstring;
#endif
⽐如java中的⽅法:
public native int test(String str, int i, long l, short s, double d, float f, char c);
⽤ javah 变成 jni的⽅法后成这样:
JNIEXPORT jint JNICALL Java_com_jni_test_EncodeJNI_test (JNIEnv *env, jobject objThis, jstring str, jint i, jlong l, jshort s, jdouble d, jfloat f, jchar c);
jlong 在 C ⾥⾯对应的 long long 类型,有64bit,输出时⽤ "%lld"
数组的传递:
public native String arrayTest(String[] strArray, int[] iArray, long[] lArray, short[] sArray, double[] dArray, float[] fArray, char[] cArray); JNIEXPORT jstring JNICALL Java_com_jni_test_EncodeJNI_arrayTest(JNIEnv *env, jobject objThis, jobjectArray strArray, jintArray
iArray, jlongArray lArray, jshortArray sArray, jdoubleArray dArray, jfloatArray fArray, jcharArray cArray); jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
jbyteArray (*NewByteArray)(JNIEnv*, jsize);
jcharArray (*NewCharArray)(JNIEnv*, jsize);
jshortArray (*NewShortArray)(JNIEnv*, jsize);
jintArray (*NewIntArray)(JNIEnv*, jsize);
jlongArray (*NewLongArray)(JNIEnv*, jsize);
jfloatArray (*NewFloatArray)(JNIEnv*, jsize);
jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize);
jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
获取数组长度: jsize (*GetArrayLength)(JNIEnv*, jarray);
设置IntArray 的值
void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, const jint* buf)
View Code
#include "com_TestCopyPix_jni.h"
//#include other headers
JNIEXPORT jintArray JNICALL Java_com_TestCopyPix_jni_ct(JNIEnv *env, jobject obj) {
//jdoubleArray inner = (*env)->NewDoubleArray(env, 3);
// int i = 1;
// jintArray array;//定义数组对象
// array = (*env)-> NewIntArray(env, 10);
// for(; i<= 10; i++)
// (*env)->SetIntArrayRegion(env, array, i-1, 1, &i);
// /* 获取数组对象的元素个数 */
// int len = (*env)->GetArrayLength(env, array);
// /* 获取数组中的所有元素 */
// jint* elems = (*env)-> GetIntArrayElements(env, array, 0);
// for(i=0; i<len; i++)
// printf("ELEMENT %d IS %d\n", i, elems[i]);
int i = 1;
int a = 20;
int b = 200;
jintArray array;//定义数组对象
array = (*env)-> NewIntArray(env, 2);
(*env)->SetIntArrayRegion(env, array, 0, 1, &a);
(*env)->SetIntArrayRegion(env, array, 1, 1, &b);
// for(; i<= 2; i++)
// (*env)->SetIntArrayRegion(env, array, i-1, 1, &i);
/* 获取数组对象的元素个数 */
// int len = (*env)->GetArrayLength(env, array);
// /* 获取数组中的所有元素 */
// jint* elems = (*env)-> GetIntArrayElements(env, array, 0);
return array;
}
View Code
jintArray
Java_com_summer_PointerTestActivity_test( JNIEnv* env,
jobject thiz,jintArray nums)
{
//获取传⼊数组的长度
jsize len = (*env)->GetArrayLength(env, nums);
//在java中申请⼀块内存以⽤来将C的数组传输给java程序
jintArray ret=(*env)->NewIntArray(env,len);
//获取传⼊的数组
jint *body = (*env)->GetIntArrayElements(env, nums, 0);
int i;
for(i=0;i<len;i++)
{
body[i] *=2;
}
//将C的数组拷贝给java中的数组
(*env)->SetIntArrayRegion(env,ret,0,len,body);
return ret;
}
String的处理
Java String不能直接被C++程序使⽤,需要先⽤ env->GetStringUTFChars把它转化为UTF编码形式的char*再进⾏处理。
如:
jboolean isCopy = 0;
str = env->GetStringUTFChars(prompt, &isCopy); //C 中是 (*env)->GetStringUTFChars(env, str, &isCopy); 这⾥返回的char*有字符串结束符
如果想返回⼀个java的String类型的话,我们可以通过env->NewStringUTF命令⽤⼀个char*来创建⼀个jstring,然后让该jstring返回就可以。
如:jstring rtstr = env->NewStringUTF(tmpstr);
上⾯的GetStringUTFChars,ReleaseStringUTFChars,NewStringUTF都是JNI提供的处理String类型的函数,更多的JNI函数请查看jin.h。
注意:在使⽤完你所转换之后的对象之后,需要显⽰调⽤ ReleaseStringUTFChars(JNIEnv*, jstring, const char*)⽅法,让JVM释放转换成UTF-8的string的对象的空间,如果不显⽰的调⽤的话,JVM中会⼀直保存该对象,不会被垃圾回收器回收,因此就会导致内存溢出。
下⾯是访问String的⼀些⽅法, C中:
◆const char*GetStringUTFChars(JNIEnv*, jstring, jboolean*); 将jstring转换成为UTF-8格式的char*
◆const jchar* GetStringChars(JNIEnv*, jstring, jboolean*); 将jstring转换成为Unicode格式的char*
◆ void ReleaseStringUTFChars(JNIEnv*, jstring, const char*); 释放指向UTF-8格式的char*的指针
◆void ReleaseStringChars(JNIEnv*, jstring, const jchar*); 释放指向Unicode格式的char*的指针
◆jstring NewStringUTF)JNIEnv*, const char*); 创建⼀个UTF-8格式的String对象
◆jstring NewString(JNIEnv*, const jchar*, jsize); 创建⼀个Unicode格式的String对象
◆jsize GetStringUTFLength)(JNIEnv*, jstring); 获取 UTF-8格式的char*的长度
◆jsize GetStringLength)(JNIEnv*, jstring); 获取Unicode格式的char*的长度。