jni回调java类中函数_Andriod JNI编程之C++回调Java函数

本文详细介绍了如何在C++代码中回调Java类的方法,包括获取类和方法ID、创建对象以及调用Java方法的步骤。通过一个具体的例子展示了C++调用Java的sayHelloFromJava方法,传递不同类型的参数,并在Java端进行处理的过程。此外,还提供了一个小技巧,通过javah生成的头文件注释来确定Java类型在C++中的对应表示。
摘要由CSDN通过智能技术生成

一般我们NDK编程都是Java层调用C++的接口,但其实才C++层也可以调用Java的函数。实现方法如下:

1、获取类名:jclass cls = env->FindClass

2、获取类方法:jmethodID mid = env->GetMethodID

3、获取类成员变量:fieldID fid=env->GetFieldID

4、生成类对象:jobject obj=env->NewObject (jobect也可以从Java层传下来)

5、调用类成员方法:env->CallXXXMethod(XXX为Java方法的返回值类型)

下面是一个例子:

首先是Java的代码,首先生成一个JniTest类,里面有个sayHelloFromJava的方法,我们要实现的目标是在C++里面赋值(String str),两个整形值(int index1,  int index2),一个整形数组(int[] intArray),然后在Java里面将这些数值打印出来。

publicclassJniTestextendsActivity {

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

JNI j = newJNI();

j.write();

}

publicJniTest()

{

Log.i("TEST","JniTest Constructor");

}

publicintsayHelloFromJava(String str,intindex1,intindex2,int[] intArray)

{

Log.i("TEST", str +" But I am show in java");

Log.i("TEST","index1 = "+ index1 +" index2 = "+ index2 );

intjavaIndex =5;

for(inti =0; i 

{

Log.i("TEST","intArray[i] = "+ intArray[i]);

}

returnjavaIndex;

}

}

publicclassJNI {

static

{

System.loadLibrary("myjni");

}

publicnativevoidwrite();

}

然后是C++里面的代码

JNIEXPORTvoidJNICALL Java_cc_androidos_jni_JNI_write

(JNIEnv *env, jobject j) {

LOGI("calltest");

jstring str = NULL;

jclass clz = env->FindClass("cc/androidos/jni/JniTest");

//获取clz的构造函数并生成一个对象

jmethodID ctor = env->GetMethodID(clz, "","()V");

jobject obj = env->NewObject(clz, ctor);

// 如果是数组类型,则在类型前加[,如整形数组int[] intArray,则对应类型为[I,整形数组String[] strArray对应为[Ljava/lang/String;

jmethodID mid = env->GetMethodID(clz, "sayHelloFromJava","(Ljava/lang/String;II[I)I");

if(mid)

{

LOGI("mid is get");

jstring str1 = env->NewStringUTF("I am Native");

jint index1 = 10;

jint index2 = 12;

//env->CallVoidMethod(obj, mid, str1, index1, index2);

// 数组类型转换 testIntArray能不能不申请内存空间

jintArray testIntArray = env->NewIntArray(10);

jint *test = newjint[10];

for(inti = 0; i 

{

*(test+i) = i + 100;

}

env->SetIntArrayRegion(testIntArray, 0, 10, test);

jint javaIndex = env->CallIntMethod(obj, mid, str1, index1, index2, testIntArray);

LOGI("javaIndex = %d", javaIndex);

delete[] test;

test = NULL;

}

}

通过这个例子我们基本上就可以了解C++层是如何回调Java函数的了。另外,这里还有一个小技巧,如果你不知道你Java层的在C++中的类型是什么,你可以native方法中将这个类型写进去,然后用javah方法生成.h文件,只要查看.h文件的对应的类型注释就可以知道结果了。例如:我们想知道String、整形数组对应的类型怎么写,我们在native中加入一个public native void type(String str, int[] arrayInt)方法

publicclassJNI {

static

{

System.loadLibrary("myjni");

}

publicnativevoidwrite();

publicnativevoidtype(String str,int[] arrayInt);

}

然后生成对应的.h文件:

/*

* Class:     cc_androidos_jni_JNI

* Method:    type

* Signature: (Ljava/lang/String;[I)V

*/

JNIEXPORT voidJNICALL Java_cc_androidos_jni_JNI_type

(JNIEnv *, jobject, jstring, jintArray);

我们注意看注释中的“Signature: (Ljava/lang/String;[I)V”,其中Ljava/lang/String;Ljava/lang/String;就是String的类型(注意分号不能丢),[I则是整形数组对应的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值