JNI C++调用Java(一)
作者:互联网
文章内容主要是记录 C++ 通过JNI对Java的调用
一、首先需要知道数据类型转换对应的关系,这个涉及到函数的调用
1、基本数据类型的转换
Java | Native | Signature |
byte | jbyte | B |
char | jchar | C |
double | jdouble | D |
float | jfloat | F |
int | jint | I |
short | jshort | S |
long | jlong | J |
boolean | jboolean | Z |
void | void | V |
2、引用数据类型的转换
Java | Native | Signature |
所有对象 | jobject | L+classname +; |
Class | jclass | Ljava/lang/Class; |
String | jstring | Ljava/lang/String; |
Throwable | jthrowable | Ljava/lang/Throwable; |
Object[] | jobjectArray | [L+classname +; |
byte[] | jbyteArray | [B |
char[] | jcharArray | [C |
double[] | jdoubleArray | [D |
float[] | jfloatArray | [F |
int[] | jintArray | [I |
short[] | jshortArray | [S |
long[] | jlongArray | [J |
boolean[] | jbooleanArray | [Z |
二、C++函数类型,参数类型要与Java方法类型,参数类型一致,通过JNI的签名表示
java方法
public native String stringFromJNI();
public void testVoid(){
Log.e(TAG,"C++调用Java testVoid");
}public static void testStaticVoid(){
Log.e(TAG,"C++调用Java testStaticVoid");
}public int testInt(){
Log.e(TAG,"C++调用Java testInt");
return 0;
}public static int testStaticInt(){
Log.e(TAG,"C++调用Java testStaticInt");
return 0;
}
C++调用方法
void testVoid(JNIEnv *env,jobject thiz){ //获取java对象类 jclass jclazz = env->GetObjectClass(thiz); /** * 获取java对象方法ID * clazz:对象类 * name:方法名 * sig:方法签名 */ jmethodID jmethodID = env->GetMethodID(jclazz, "testVoid", "()V"); /** * obj:参数是对象 * methodID: 方法名ID * ... :动态参数(有几个就传几个对应类型的参数) */ env->CallVoidMethod(thiz, jmethodID); } static void testStaticVoid(JNIEnv *env,jobject thiz){ //获取java对象类 jclass jclazz = env->GetObjectClass(thiz); /** * 获取java对象方法ID * clazz:对象类 * name:方法名 * sig:方法签名 */ jmethodID jmethodID = env->GetStaticMethodID(jclazz, "testStaticVoid", "()V"); /** * clazz:参数是类 * methodID: 方法名ID * ... :动态参数(有几个就传几个对应类型的参数) */ env->CallStaticVoidMethod(jclazz, jmethodID); } void testInt(JNIEnv *env,jobject thiz){ //获取java对象类 jclass jclazz = env->GetObjectClass(thiz); /** * 获取java对象方法ID * clazz:对象类 * name:方法名 * sig:方法签名 */ jmethodID jmethodID = env->GetMethodID(jclazz, "testInt", "()I"); /** * obj:参数是对象 * methodID: 方法名ID * ... :动态参数(有几个就传几个对应类型的参数) */ env->CallIntMethod(thiz, jmethodID); } static void testStaticInt(JNIEnv *env,jobject thiz){ //获取java对象类 jclass jclazz = env->GetObjectClass(thiz); /** * 获取java对象方法ID * clazz:对象类 * name:方法名 * sig:方法签名 */ jmethodID jmethodID = env->GetStaticMethodID(jclazz, "testStaticInt", "()I"); /** * clazz:参数是类 * methodID: 方法名ID * ... :动态参数(有几个就传几个对应类型的参数) */ env->CallStaticIntMethod(jclazz, jmethodID); }
运行结果
通过上面的四个函数对比:
static 静态与非静态对比:
静态使用:
获取方法ID:GetStaticMethodID()
调用方法:CallStaticVoidMethod()
非静态:
获取方法ID:GetMethodID()
调用方法:CallVoidMethod()
void 与 int的对比
void 与int 获取方法ID是一样的:非静态使用:GetMethodID() ,静态使用GetStaticMethodID()
调用方法:
void使用:
非静态方法:
env->CallVoidMethod(thiz, jmethodID)
静态方法:
env->CallStaticVoidMethod(jclazz, jmethodID);
int使用:
非静态方法:
env->CallIntMethod(thiz, jmethodID);
静态方法:
env->CallStaticIntMethod(jclazz, jmethodID);
通过上面的void与int的静态方法和非静态方法也就能知道float,double,long的使用了;
标签:thiz,jclazz,Java,C++,jmethodID,env,JNI,方法,ID 来源: https://blog.csdn.net/u011905195/article/details/112393826