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

I am learning to use JNI, and there are garbled characters when I use 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

这是实现native的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: %s\n", c_str);
    if (c_str == NULL) {
        printf("out of memory.\n");
        return NULL;
    }
    // 替换字符串
    (*env)->ReleaseStringUTFChars(env, j_str, c_str);
    // 打印
    printf("Java Str:%s\n", c_str);
    sprintf(buff, "hello %s\n", 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时出现乱码?

来自the JNI manual

ReleaseStringUTFChars

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

Informs the VM that the native code no longer needs access to utf. The utf argument is a pointer derived from string using GetStringUTFChars().

所以很明显,在告诉 VM 您不再需要它之后使用 c_str 是一个错误。构建 buff

后调用 ReleaseStringUTFChars()