当前位置: 首页 > 知识库问答 >
问题:

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

池宸
2023-03-14

我正在学习manjaro系统下JNI的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时会出现乱码?

共有1个答案

鞠边浩
2023-03-14

摘自JNI手册

ReleaseStringUtfChars

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

通知VM本机代码不再需要访问UTF。utf参数是使用GetStringUTFChars()从string派生的指针。

因此,在告诉VM不再需要c_str之后使用它显然是一个bug。生成缓冲区后,只需调用ReleaseStringUtfChars()

 类似资料:
  • /*错误:在SMTPConnection中缺少“PLAIN”的凭据。_formatError(C:\User\dhruv singhal\Desktop\web_development_project\node_modules\nodemailer\lib\smtp-Connection\index.js:774: 19)在SMTPConnection.login(C:\User\dhruv si

  • 我有一张表有这样的关系: 我打电话给孙子、孩子和父母只是为了说明这个问题...不是继承问题 Child.java 我正试图直接删除一个带有级联类型的父对象。我觉得没什么问题。但当我试图删除时,我得到: 08-26 11:36:33,755错误[SqlExceptionHelper]无法删除或更新父行:外键约束失败(.>id))2020-08-26 11:36:33,773信息[AbstractBa

  • 使用JNI时的java.lang.UnsatisfiedLinkError。 我的测试环境: Ubuntu 12.04/64位 JDK 1.7 gcc(Ubuntu/Linaro 4.6.3-1Ubuntu5) 已提取java_tool_options:-dfile.encoding=utf8 java.library.path=.:/home/mancook/cook/work/stsoftwa

  • 我已在我的Android文件中的应用程序标记之外设置了所有设置: 但是当我尝试捕捉屏幕时,我收到以下错误: JAVA木卫一。FileNotFoundException:/storage/simulated/0/DCIM/Camera/EMOJI_2-7-116_22538。jpg:打开失败:EACCES(权限被拒绝) 这是捕获屏幕的方法。 帮我如何解决这个问题?

  • 在尝试从cpp类调用java中的函数以在memmory中保存布尔值时,出现以下错误。我正在使用一个名为MyAdapter的类。cpp调用MyAdapterJni函数。cpp。我用MyAdapterJni编写了以下函数。清洁石油产品 我在myManager中有以下功能。java类 我在我的logcat上得到以下日志 12-14 12:06:32.024: W/dalvikvm(9575):异常Lja

  • 我正在尝试使用Alamofire4.8.2将一组图像上传到服务器 以下是函数: 在下面的行中获取错误: 无法使用类型为“(UIImage,withName:String,fileName:String,mimeType:String)”的参数列表调用“append”