编程语言
首页 > 编程语言> > JNI C++调用Java(一)

JNI C++调用Java(一)

作者:互联网

文章内容主要是记录 C++ 通过JNI对Java的调用

一、首先需要知道数据类型转换对应的关系,这个涉及到函数的调用

1、基本数据类型的转换

JavaNativeSignature
bytejbyteB
charjcharC
doublejdoubleD
floatjfloatF
intjintI
shortjshortS
longjlongJ
booleanjbooleanZ
voidvoidV

2、引用数据类型的转换

JavaNativeSignature
所有对象jobjectL+classname +;
ClassjclassLjava/lang/Class;
StringjstringLjava/lang/String;
ThrowablejthrowableLjava/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