如何正确地将 java 中的字节数组转换为 jni 中的 char 指针

how to properly convert byte array in java to char pointer in jni

我是 C/C++ 的新手,所以我不知道如何正确地将 Java 中的字节数组转换为 JNI 中的字符数组。

例如,我有一个包含"Hello world!"inputString,我用它来获取字节数组:

byte[] data = inputString.getBytes();

然后在JNI层,我使用:

jbyte *array = (*env)->GetByteArrayElements(env, data, &isCopy);
argv[1] = (char *)array;

然后当我打印 argv[1] 时,它是 "Hello world!ZE"

这里为什么多了个字符"ZE"

谁能解释一下,并提供将 byte[] 指针转换为 char* 指针的正确解决方案?我需要 char* 指针,因为给我的接口对我来说是 char* 指针。

您的 byte[] 数组不是以 null 结尾的(不以 0x00 字节结尾),但您显然将其视为是。打印字节时,“额外”字符是当打印访问超出数组边界时来自周围内存的随机值,这是 未定义的行为

使用(*env)->GetArrayLength()找出数组中实际有多少字节,然后不要访问比这更多的字节,例如:

jint len = (*env)->GetArrayLength(env, data);
jbyte *array = (*env)->GetByteArrayElements(env, data, &isCopy);
argv[1] = (char*) array;
...
printf("%.*s", len, argv[1]);
...
(*env)->ReleaseByteArrayElements(env, data, array, JNI_ABORT);

如果你真的需要一个以 null 结尾的字符串(或者只需要保留比 Java byte[] 数组更长的数据),你将不得不分配你自己的 char[] 缓冲区,为终止符留出额外空间,然后将 byte[] 数组数据复制到该缓冲区,例如:

jint len = (*env)->GetArrayLength(env, data);

jbyte *array = malloc(len + 1);
if (array) {
    (*env)->GetByteArrayRegion(env, data, 0, len, array);
    array[len] = 0x00;
}

argv[1] = (char*) array;
...
printf("%s", argv[1]);
...
free(argv[1]);