将jbyteArray转换为一个字符数组,然后打印到控制台

 2023-01-20    260  

问题描述

我正在编写一个JNI程序,其中.cpp文件获取JBYTEARRAY,我希望能够用printf打印JBYTEARRAY.为此,我相信我必须将jbytearray转换为角色阵列.

作为背景知识,我的JNI的Java侧将字符串转换为bytearray,然后将Bytearray作为参数传递给我的JNI函数.

将jbyteArray转换为一个字符数组,然后打印到控制台

我到目前为止所做的事情正确打印出了字符串,但随后是垃圾字符,我不知道如何摆脱这些/如果我做错了什么.

这是字符串是:

dsa

以及哪些打印要控制:

dsa,�

垃圾字符会根据字符串是什么而改变.
这是相关代码的一部分:

.java文件:

public class tcr extends javax.swing.JFrame{

static{
    System.loadLibrary("tcr");
}

public native int print(byte file1[]);

    .....

    String filex1 = data1TextField.getText();//gets a filepath in the form of a String from a GUI jtextfield.
    byte file1[]= filex1.getBytes();//convert file path from string to byte array

        tcr t = new tcr();
        t.print(file1);
}

.cpp代码:

JNIEXPORT jint JNICALL Java_tcr_print(JNIIEnv *env, jobject thisobj, jbyteArray file1){

    jboolean isCopy;
    jbyte* a = env->GetByteArrayElements(file1,&isCopy);    char* b;
    b = (char*)a;
    printf("%s\n",b);}

任何帮助将不胜感激.

推荐答案

看你在做什么:

jbyte* a = env->GetByteArrayElements(file1,&isCopy);

a现在指向存储字符串字节内容的内存地址.假设文件包含字符串” Hello World”.在UTF-8编码中,那将是:

48 65 6c 6c 6f 20 77 6f 72 6c 64

char* b = (char*)a;

b现在指向该内存区域.这是一个炭指针,因此您可能想将其用作C字符串.但是,那行不通. c字符串定义为某些字节,以零字节结尾.现在抬头在那里,您会发现该字符串末尾没有零字节.

printf("%s\n",b);

在这里.您将炭指针传递给printf as %s,它告诉printf它是一个C字符串.但是,它不是C字符串,但printf仍然试图打印所有字符,直到达到零字节为零.因此,在字节阵列结束后,您在dsa之后看到的是从内存中的字节,直到(偶然)零字节为零.您可以通过将字节复制到一个比字节数组长,然后将最后一个元素设置为零来解决此问题.

.

更新:

您可以创建较大的缓冲区并像这样附加null字节:

int textLength = strlen((const char*)a);
char* b = malloc(textLength + 1);
memcpy(b, a, textLength);
b[textLength] = '\0';

现在b是一个有效的null终止c字符串.另外,不要忘记ReleaseByteArrayElements的呼叫.您可以在memcpy通话后立即执行此操作.

其他推荐答案

jbytearray实际上是通过JNI传递Java字符串的一种很好的方法.它使您可以轻松地将字符串转换为字符集,并通过在C ++侧使用的库和文件/设备所需的编码.

确保您理解” 绝对最低的每个软件开发人员绝对,积极地必须了解Unicode和cartar集(无借口!)”

Java字符串使用Unicode字符集和UTF-16编码(带有平台依赖的字节顺序).

string.getBytes( )转换为”平台的默认字符”.因此,它对您需要的字符集和编码以及对目标字符集中不在的字符做些什么假设.您可以使用其他Java String.getBytes Overlads或Charset方法,如果您想明确控制这些内容.

在确定要使用的字符集和编码时,请考虑使用Unicode已使用了几十年,用作Java,.net,VB,…的主要字符串类型.在Java的编译器源文件中,…;通常在www.当然,您可能会受到要与之互操作的东西的限制.

现在,似乎您面临的问题是,目标字符集是缺少Java字符串和替代品的字符,或者您使用的控制台无法正确显示它们.

显然,控制台(或带有UI的任何应用程序)必须选择一个字体来渲染字符.字体通常不支持Unicode中可用的百万个编码点.您可能可以更改控制台的配置(或使用另一个).例如,在Windows中,您可以使用CMD.EXE或PS(Windows PowerShell).您可以更改cmd.exe Windows中的字体,然后使用chcp更改字符集.

更新:

as @main-指出,如果您使用的是期望终结器附加到字符串上的函数,则必须提供它,通常是通过复制数组来提供的函数,因为JVM保留了数组的所有权.在这种情况下,这是行为的实际原因.但是,以上所有内容也很重要.

以上所述是小编给大家介绍的将jbyteArray转换为一个字符数组,然后打印到控制台,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25972.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。