JNI内通过参数形式从C/C++中传递string类型数据至Java层
Posted nanke_yh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的数据内容了。
以上是关于JNI内通过参数形式从C/C++中传递string类型数据至Java层的主要内容,如果未能解决你的问题,请参考以下文章
将参数从 C/C++ JNI 传递到 Java 并获取修改后的值
java 通过jni 向 c 传递一个 java 对象, c 如何取得这个对象的属性值?