JNI类型和Java类型对应关系
Java类型JNI类型真实C++类型booleanjbooleanuint8_t,unsigned charbytejbyteint8_t,signed charcharjcharuint16_t,unsigned shortshortjshortint16_t,shortintjintint32_t,intlongjlongint64_t,long longfloatjfloatfloatdoublejdoubledoubleObjectjobjectc++ classClassjclassc++ class,继承jobjectStringjstringc++ class,继承jobjectboolean[]jbooleanArrayc++ class,继承jarray和jobjectbyte[]jbyteArrayc++ class,继承jarray和jobjectchar[]jcharArrayc++ class,继承jarray和jobjectshort[]jshortArrayc++ class,继承jarray和jobjectint[]jintArrayc++ class,继承jarray和jobjectlong[]jlongArrayc++ class,继承jarray和jobjectfloat[]jfloatArrayc++ class,继承jarray和jobjectdouble[]jdoubleArrayc++ class,继承jarray和jobjectObject[]jobjectArrayc++ class,继承jarray和jobjectClass[]jobjectArrayc++ class,继承jarray和jobjectString[]jobjectArrayc++ class,继承jarray和jobjectJNI类型和方法签名
在C++代码中,可以通过反射获取Java中的方法和类型
Java中的每个类型和方法,都对应一个唯一字符串,这个就是签名
Java类型签名booleanZbyteBcharCshortSintIlongLfloatFdoubleDObjectL+包名+分号[][+类型签名[][][[+类型签名方法(参数签名)+返回值签名签名示例如下
Java类型签名StringLjava/lang/String;ObjectLjava/lang/Object;String[][Ljava/lang/String;int func(int i, Object object)(ILjava/lang/Object;)IC++接收和创建Java类对象
//通过JNI复制一个Java对象
native Point native_copy_object(Point object);
//调用JNI方法复制对象
Point srcObject = new Point(5, 10);
Point dstObject = native_copy_object(srcObject);
//C++实现JNI函数
extern "C" JNIEXPORT jobject JNICALL
Java_easing_android_media_MediaPlayer_native_1copy_1object(JNIEnv *env, jobject obj, jobject srcObject) {
//找到Point对应的Class
jclass dstClazz = env->FindClass("android/graphics/Point");
//获取srcObject的字段值
jfieldID xFieldId = env->GetFieldID(dstClazz, "x", "I");
jfieldID yFieldId = env->GetFieldID(dstClazz, "y", "I");
jint x = env->GetIntField(srcObject, xFieldId);
jint y = env->GetIntField(srcObject, yFieldId);
//创建一个新的Point对象
jobject dstObject = env->AllocObject(dstClazz);
//拷贝srcObject的字段给dstObject
env->SetIntField(dstObject, xFieldId, x);
env->SetIntField(dstObject, yFieldId, y);
//返回新的Point给Java
return dstObject;
}
Java接收和创建C++类对象
C++对象是没法传递给Java层的
因为在C++中,有jobject对应Java中的类型,但在Java中,却没有数据类型能够对应C++中的类类型
但我们却可以通过方法封装,快速将C++对象转为Java对象,再传递给Java,或是将收到的Java对象,快速转为C++对象
struct Point {
public:
int x;
int y;
//从JavaObject创建一个C++Object
static Point *fromJavaObject(JNIEnv *&env, jobject &interface, jobject &javaObject) {
Point *point = new Point();
jclass clazz = env->FindClass("android/graphics/Point");
jfieldID xFieldId = env->GetFieldID(clazz, "x", "I");
jfieldID yFieldId = env->GetFieldID(clazz, "y", "I");
point->x = env->GetIntField(javaObject, xFieldId);
point->y = env->GetIntField(javaObject, yFieldId);
return point;
}
//从C++Object创建一个JavaObject
static jobject toJavaObject(JNIEnv *&env, jobject &interface, Point *&cppObject) {
Point *point = new Point();
jclass clazz = env->FindClass("android/graphics/Point");
jfieldID xFieldId = env->GetFieldID(clazz, "x", "I");
jfieldID yFieldId = env->GetFieldID(clazz, "y", "I");
jobject javaObject = env->AllocObject(clazz);
env->SetIntField(javaObject, xFieldId, cppObject->x);
env->SetIntField(javaObject, yFieldId, cppObject->y);
return javaObject;
}
};