java byte 数组打印,将jbyteArray转换为字符数组,然后打印至控制台

这篇博客讨论了在JNI编程中如何将Java的jbyteArray转换为C字符串并正确打印。作者遇到了打印后出现垃圾字符的问题,原因是未正确处理C字符串的终止符。解决方案是创建一个比原始字节数组长度多一个字节的缓冲区,并在末尾添加零字节以形成有效的C字符串。同时,别忘了释放ByteArrayElements。
摘要由CSDN通过智能技术生成

I am writing a JNI program where my .cpp file gets a jbyteArray and I want to be able to print the jbyteArray with printf. For that to happen, I believe I have to convert the jbyteArray to a character array.

For background knowledge, the java side of my JNI converts a String to a byteArray, and then that byteArray is passed in as an argument to my JNI function.

What I've done so far prints out the String correctly, but it is followed by junk characters, and I do not know how to get rid of these/if I am doing something wrong.

Here is what the String is:

dsa

and what prints to console:

dsa,�

The junk characters change depending on what the String is.

Here is the part of the code that is relevant:

.java file:

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 code:

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);

}

Any help would be appreciated.

解决方案

Look what you are doing:

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

a now points to a memory address where the byte contents of the string are stored. Let's assume that the file contains the string "Hello world". In UTF-8 encoding, that would be:

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

char* b = (char*)a;

b now points to that memory region. It's a char pointer, so you probably want to use it as a C string. However, that won't work. C strings are defined as some bytes, ending with a zero byte. Now look up there and you'll see that there is no zero byte at the end of this string.

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

Here it is. You are passing the char pointer to printf as %s which tells printf that it's a C string. However, it isn't a C string but printf still tries to print all characters until it reaches a zero byte. So what you see after dsa are actually bytes from your memory after the end of the byte array until there is (by coincidence) a zero byte. You can fix this by copying the bytes to a buffer that is one byte longer than the byte array and then setting the last element to zero.

UPDATE:

You can create the bigger buffer and append the null byte like this:

int textLength = strlen((const char*)a);

char* b = malloc(textLength + 1);

memcpy(b, a, textLength);

b[textLength] = '\0';

Now b is a valid null-terminated C string. Also, don't forget the call to ReleaseByteArrayElements. You can do that right after the memcpy call.

要将JNI中的char*类型转换Java中的byte数组,可以按照以下步骤进行操作: 1. 获取char*类型字符串的长度,使用strlen()函数可以获取。 2. 创建一个jbyteArray类型的Java数组,长度为字符串长度,使用NewByteArray()函数可以创建。 3. 将char*类型字符串转换为jbyte类型数组,使用jbyte*类型的指针指向char*类型字符串,然后使用SetByteArrayRegion()函数将每个char类型元素转换为jbyte类型并设置到Java数组中。 4. 释放char*类型字符串的内存空间,使用free()函数释放。 下面是一个示例代码: ```c++ JNIEXPORT jbyteArray JNICALL Java_com_example_MyClass_charToByteArray(JNIEnv *env, jobject obj, jcharArray charArray) { // 将jcharArray类型转换为jchar类型指针 jchar *chars = env->GetCharArrayElements(charArray, NULL); // 获取字符串长度 int len = strlen(chars); // 创建jbyteArray类型的Java数组 jbyteArray byteArray = env->NewByteArray(len); // 将char*类型字符串转换为jbyte类型的数组 jbyte *bytes = (jbyte*)chars; env->SetByteArrayRegion(byteArray, 0, len, bytes); // 释放char*类型字符串的内存空间 free(chars); // 返回jbyteArray类型的Java数组 return byteArray; } ``` 在上面的示例代码中,我们首先将输入的jcharArray类型转换为jchar类型指针,然后获取字符串长度。接着,我们使用NewByteArray()函数创建一个长度为字符串长度的jbyteArray类型的Java数组。然后,我们将jchar类型指针转换为jbyte类型指针,并使用SetByteArrayRegion()函数将每个char类型元素转换为jbyte类型并设置到Java数组中。最后,我们使用free()函数释放char*类型字符串的内存空间,并返回jbyteArray类型的Java数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值