我正在学习使用JNI,当我使用ReleaseStringUTFChars时,会出现乱码



我正在学习 JNI 在 manjaro 系统下的 API 用法。 这是一个 Java 本机函数声明。

/**
* @author aszswaz
* @date 2021/4/15 20:00:36
*/
public class HelloWorld {
static {
System.loadLibrary("HelloWorld");
}
/**
* 声明 native方法
*/
public static native String sayHello(String name);
public static void main(String[] args) {
// 调用函数
String text = sayHello("yangxin");
System.out.println(text);
}
}

这是生成的 JNI 头文件。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     HelloWorld
* Method:    sayHello
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_HelloWorld_sayHello
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif

这是实现本机的 C 语言代码。

//
// Created by aszswaz on 2021/4/15.
//
#include "HelloWorld.h"
#include "stdio.h"
JNIEXPORT jstring JNICALL Java_HelloWorld_sayHello(JNIEnv *env, jclass aClass, jstring j_str) {
const char *c_str = NULL;
char buff[128] = {0};
// 开辟一块新的内存用于存储字符串,如果内存不够了,会获取失败
c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
printf("origin str: %sn", c_str);
if (c_str == NULL) {
printf("out of memory.n");
return NULL;
}
// 替换字符串
(*env)->ReleaseStringUTFChars(env, j_str, c_str);
// 打印
printf("Java Str:%sn", c_str);
sprintf(buff, "hello %sn", c_str);
return (*env)->NewStringUTF(env, buff);
}

这是我执行的编译和运行指令。

$ javac HellWorld.java
$ javah -jni HelloWorld
$ gcc -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -fPIC -shared HelloWorld.c HelloWorld.h -o libHelloWorld.so
$ java -Djava.library.path=. HelloWorld

这是操作的结果。

origin str: yangxin
Java Str:%gz�
hello %gz±

为什么它看起来异常,我该如何解决? 我尝试删除ReleaseStringUTFChars函数,它可以正常输出。为什么当我添加 ReleaseStringUTFChars 时它看起来是乱码?

来自 JNI 手册

ReleaseStringUTFChars

void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);

通知 VM 本机代码不再需要访问 utf。这 utf 参数是从字符串派生的指针,使用 GetStringUTFChars().

因此,很明显,在告诉 VM 您不再需要它之后使用c_str是一个错误。只需在构建buff后致电ReleaseStringUTFChars()

相关内容

  • 没有找到相关文章

最新更新