package com.test.mytest;
public final class SensorNative {
static {
System.loadLibrary("MYJNI");
Init();
}
private native static void Init();
public native static int GetY();
...
}
其中,注意native关键字,一个Native Method就是一个java调用非java代码的接口,标识符native可以与所有其它的java标识符(abstract除外)连用.
我们这里的MYJNI是C++文件,在MYJNI.C++文件中:
extern "C" void Java_com.test.mytest_SensorNative_Init(JNIEnv* env, jobject thiz) {
...
}
extern "C" jint Java_com.test.mytest_SensorNative_GetY(JNIEnv* env, jobject thiz) {
return g_y;
}
这里可以看出,在JNI.c++文件中,函数体实现的时候,命名应该是:Java_包名_类名_方法名,参数和返回值应转换为JNI类型,如jint,jboolean.
重点:JNI函数与API
在目前的应用中,我们主要关心的是C/C++数据类型与JNI本地类型之间的转化过程,这个过程某些数据的转换需要使用JNIEnv对象的一系列方法来完成。
1.jstring转换为C风格字符串
char* test = (char*)(*env)->GetStringUTFChars(env,jstring,NULL);
(*env)->ReleaseStringUTFChars(env, jstring, test);
记得使用完毕后,应调用release释放资源。
2.C风格字符串转换为
jstring char charStr[50];
jstring jstr;
jstr = env -> NewStringUTF(charStr);
3.C语言中获取的一段char*的buffer传递给Java 在jni中new一个byte数组,然后使用(*env)->SetByteArrayRegion(env, bytearray, 0, len, buffer) 操作将buffer拷贝到数组中。这种方式主要是针对buffer中存在“\0”的情况,如果以C风格字符串的方式读入,就会损失“\0”之后的字符
(重中之重)返回值是数组的情况:以jintArray为例,有一系列的操作函数:GetArrayLength 返回数组中的元素数
NewIntArray 创建一个指定长度的原始数据类型数组
GetIntArrayElement 返回Int数组的元素
SetIntArrayElement 设置Int数组的元素
GetIntArrayRegion 将原始数据类型数组中的内容拷贝到预先分配好的内存缓存中
SetIntArrayRegion 设置缓存中数组的值
ReleaseIntArrayRegion 释放GetIntArrayRegion分配的内存