JNI内通过参数形式从C/C++中传递string类型数据至Java层

Posted nanke_yh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JNI内通过参数形式从C/C++中传递string类型数据至Java层相关的知识,希望对你有一定的参考价值。

目录

0  前言

1 string类型参数形式传值

2 测试和结果


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 如何取得这个对象的属性值?

Android jni/ndk编程二:jni数据类型转换(primitive,String,array)

JNI内形参从C代码中获取返回值并返回到Java层使用

JNI 回调传递给 C

Android NDK将参数传递给本机方法