JNI学习(三)
记录一下今天学习jni踩的一些坑,还有在踩坑中学到的东西
1.C/C++层如何返回对象
java如果要获得C/C++
层返回的值,只需要在c/c++
层对应的实现方法中返回要返回给java层的值即可,例如:
static jobject getobject(JINEnv *env,jobject obj)
jobject obj = obj;
return obj;
2.c/c++
层如何返回String
因为String是java的一个对象,对应的jni类型是jstring,所以我们需要返回的对象应该是一个jstring对象,但是在c/c++
中没有jstring这个类型,我们无法直接通过return “hello world”,这种方式来返回jstring,如果我们这样写的话,Android里面会报错:
Attempted to unregister already unregistered input channel '238d6f0f com.jxm.udpmulticast/com.jxm.test.MainActivity (server)'
ActivityManager: Exception thrown during pause android.os.DeadObjectException
这是因为”hello world”在c/c++中是一个char类型数组,我们如何返回jstring呢,这就要用到了JNIEnv的一个方法
NewStringUTF(char*)
,这个方法可以把一个char数组转换成为一个UTF编码的jstring对象,我们就可以将这个对象返回了。
3.如何在c/c++
层调用java层的代码.我们既然可以在java层调用c/c++层的代码,也能在c/c++层调用java层的代码,调用的方式如下
//native层
static void Toast(JNIEnv *env, jobject obj) {
//获取jclass对象
jclass clazz = env->GetObjectClass(obj);
//获取jmethodID对象
jmethodID mid = env->GetMethodID(clazz, "showToast", "(Ljava/lang/String;)V");
if (mid == 0)
return;
char s[] = "c++ from java";
jstring str = env->NewStringUTF(s);
//调用Java函数
env->CallVoidMethod(obj, mid,str);
}
//java层
public void showToast(String str){
Toast.makeText(mContext,str, Toast.LENGTH_SHORT).show();
}
4.java.lang.NoSuchMethodError: no non-static method "Lcom/jxm/test/NDK;.showToast(Ljava/lang/String;)V;"
这个错误发生的原因是因为”(Ljava/lang/String;)V;”中V后面多了一个’;’,JNI规则中,只有参数为jobject时,才在后面加上’;’。