4

我正在尝试char*在 android 中使用 JNI 从 C++ 传递到 java。我尝试了多种方法来传递该数据

1)使用NewStringUTF

const char* data = getData(); // this method returns a char array.
env->NewStringUTF(data);

执行上述代码会引发以下错误

JNI WARNING: input is not valid Modified UTF-8: illegal continuation byte 0x70.

2)使用NewString

const char* data = getData(); // this method returns a char array.
// passing a byte array to java
jbyteArray trackIDArray = env->NewByteArray(strlen(data));
env->SetByteArrayRegion(trackIDArray, 0, strlen(data), (const jbyte*)trackID);

在 java 方面,我得到了一些垃圾值。我不明白如何将此char数组用于 Java。

4

4 回答 4

2

我会怀疑data而不是trackID.

env->SetByteArrayRegion(trackIDArray, 0, strlen(data), (const jbyte*)data);

然后你有字节并且在java端可能会查看它是什么编码 - 通过十六进制转储或其他检查。

之后:

String s = new String(data, "Cp1252"); // Or so.
于 2013-02-19T14:19:42.853 回答
2

1) 你data的根本不是一个有效的 UTF-8 字符串。并非每个 char 数组都会自动成为有效的 UTF-8。你可能有它的一些单字节编码(如 ISO 或 Windows CP),或者它根本不是一个可读的字符串。

2) 应该没问题,但是显示trackIDdata. 您需要对其进行硬类型转换的事实jbyte*是可疑的。此代码可能是正确的,但您也可能在 Java 方面犯错误:

如果data不是可读字符串或不是“平台的默认字符集”的单字节编码 java.lang.String(byte[]) 构造函数将无法从中生成可读字符串!在这种情况下,您必须在 C 端转换为 UTF-8。您还将摆脱对平台特定编码的依赖(可能大不相同)。

于 2013-02-19T14:11:48.917 回答
2

NewStringUTF 期望您传递修改后的 UTF-8 字符串。您可能正在尝试通过 UTF-8。

有多种方法可以修复它:最明显的一种是将字符串编码为用 C++ 修改的 UTF-8,然后再将其传递给 Java。

另一种方法是将其作为字节数组传递给 Java,并使用 String 构造函数将其从 UTF-16 转换。

第二种方式可能更有效,因为最终 Java 使用 UTF-16 进行字符串表示。

作为一种替代方法,您可以在 C++ 中将字符串转换为 UTF-16,并将其传递给需要 UTF-16 的 newString JNI 函数。

于 2017-07-27T01:20:20.057 回答
0

我在 JNI 后面放置了非常大的字节源(>2kbyte),如下所示:

csv 表的内容:

R"xxx(tbl_Cbla,Column 02,Column 03,Column 04
sdfsdsad,sdfasd,dsfaddf,fdsasdf,fafasa
18,1,10,8,0)xxx"`
std::string data1 =
#include "big_table1.csv" 
;

std::string data2 =
#include "big_table2.csv"
;

extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_example_bigData_rawResource(
        JNIEnv *env,
        jobject /* this */, jint index) {

    std::string values;

    switch (index) {
        case 0: {values = data1;break;}
        case 1: {values = data2;break;}
    }

    int byteCount = values.length();
    jbyteArray ret = env->NewByteArray(byteCount);
    const jbyte* pNativeMessage = reinterpret_cast<const jbyte*>(values.c_str());
    env->SetByteArrayRegion (ret, 0, byteCount, pNativeMessage);
    return ret;
}

在 Java 中,你可以像这样取回它,导入本机函数取决于你:

ByteArrayInputStream bis = null;
try {

   bis = new ByteArrayInputStream(rawResource(1);
} catch (Exception e) {
   e.printStackTrace();
}
BufferedReader buffer = new BufferedReader(new InputStreamReader(bis,   Charset.forName("UTF-8")));

处理缓冲的阅读器也取决于你,小例子:

Strig line = buffer.readLine(); 
while ((line = buffer.readLine()) != null) {
 //play around with 'line'
}
于 2019-05-12T15:46:50.190 回答