java 通过jni 向 c 传递一个 java 对象, c 如何取得这个对象的属性值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 通过jni 向 c 传递一个 java 对象, c 如何取得这个对象的属性值?相关的知识,希望对你有一定的参考价值。
java 通过jni 向 c 传递一个 java 对象(简单对象 只有属性,java对这个对象属性进行赋值后传递给c), c 如何取得这个对象的属性值?
取得后,如何 对这个属性重新赋值并返回?
JNIEXPORT jobject JNICALL Java_com_oracle_estt_sc_db_impl_SCQueryODBC__1getCustomer
(JNIEnv *env, jobject, jobject customer)
jmethodID methodId;
//获得customer对象的句柄
jclass cls_objClass=env->GetObjectClass(customer);
//获得customer对象中特定方法getName的id
methodId=env->GetMethodID(cls_objClass,"getName","()Ljava/lang/String;");
//调用customer对象的特定方法getName
jstring js_name=(jstring)env->CallObjectMethod(customer,methodId,NULL);
...
然后C向java传递对象方法如下:
JNIEXPORT jobject JNICALL Java_perfecter_jni_LoadJni_getJavaObj(JNIEnv* env,
jobject obj)
jclass clazz=env->FindClass("perfecter/jni/MyObj");
if(clazz==0)
return 0;
jobject jobj=env->AllocObject(clazz);
jfieldID fieldId=env->GetFieldID(clazz,"name","Ljava/lang/String;");
env->SetObjectField(jobj,fieldId,env->NewStringUTF("wahaha"));
return jobj;
java对应的native方法申明public static native MyObj getJavaObj(); 参考技术A 可以用json。就是将一个对象序列化成一种格式的字符串。然后在c进行解析,或者编制。
JNI内通过参数形式从C/C++中传递string类型数据至Java层
目录
0 前言
类似之前我写过的两篇文章:一篇介绍了在JNI中基础类型int的传值方式;一篇详细梳理了在JNI层中多维数组的多种传值方式。
JNI内两种方式从C/C++中传递一维、二维、三维数组数据至Java层详细梳理_nanke_yh的博客-CSDN博客
JNI内形参从C代码中获取返回值并返回到Java层使用-CSDN博客
这篇则主要是讲JNI中String类型的数据如何通过参数的形式传递数据值。
1 string类型参数形式传值
对于JNI层传递string类型数据的网络检索,出现的并不多。大多都是讲通过return方式进行内容传递的,大家大可参考:JNI String类型 - 知乎 (zhihu.com),内部有相关理论介绍可以了解。
通过参数形式传递string类型数据具体借鉴了下文:JNI 通过形参String返回数据的方法_jni string 参数返回_Cosmo_Wang1989的博客-CSDN博客
本文具体的其实也是将string传递成StringBuffer类型,即以StringBuffer作为参数传入获取内部string数据。如此在c/c++中就有了以下的实现代码:(具体的分析解释看代码中的注释)
//最终实际传出的数据类型为StringBuffer
JNIEXPORT jint Java_com_test_java_JNItest_testString
(JNIEnv *env, jobject, jobject result)
string sstr = "Hello world!";
//str.c_str()转成const char*
const char* str = sstr.c_str();
//jstring的类型
jclass strClass = (env)->FindClass("Ljava/lang/String;");
//methodID
jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
//通过字符数组存储字符串
jbyteArray bytes = (env)->NewByteArray(strlen(str));
(env)->SetByteArrayRegion(bytes, 0, strlen(str), (jbyte*)str);
//规定字符为UTF-8
jstring encoding = (env)->NewStringUTF("UTF-8");
//得到jstring类型的数据 //若采用return方式传出的话,则可以直接返回temp。
jstring temp=(jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);
//获取需要传出去result参数类型
jclass outputJcls = env->GetObjectClass(result);
//根据result数据类型获取append操作的methodID
jmethodID appendJmId = env->GetMethodID(outputJcls, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
//再根据methodID将jstring传到参数result上
env->CallObjectMethod(result, appendJmId, temp);
return 0;
2 测试和结果
针对上述的代码实现,在java层调用native并测试:
public native int testString(StringBuffer result);
main函数内测试代码:
JNItest JNI = new JNItest();
StringBuffer output = new StringBuffer();
int rnt = JNI.testString(output);
//StringBuffer通过toString即可转为String
System.out.println(output.toString());
其中StringBuffer通过toString即可转为String,关于Java中这些字符串类型之间关系可参考:Java中字符数组、String类、StringBuffer三者的相互转换 - 功夫 熊猫 - 博客园 (cnblogs.com)
最后运行结果如下:
根据结果可以发现,output获取了c/c++层内部sstr的数据内容了。
以上是关于java 通过jni 向 c 传递一个 java 对象, c 如何取得这个对象的属性值?的主要内容,如果未能解决你的问题,请参考以下文章
使用 JNI(更具体地说是 Android NDK)时,Java 是不是通过引用或值传递给 C
JNI内通过参数形式从C/C++中传递string类型数据至Java层