我正在学习使用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时出现乱码?
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()
正在学习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时出现乱码?
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()