我正在尝试使用Android中的JNI将char*
从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。
答案 0 :(得分:2)
1)您的data
根本不是有效的UTF-8字符串。并非每个char数组都自动为有效的UTF-8。您可能在某些单字节编码(如ISO或Windows CP)中使用它,或者它根本不是可读字符串。
2)应该没问题,但是显示从trackID
填充data
的代码。您需要将其强制转换为jbyte*
的事实是可疑的。 此代码可能是正确的,但您也可能在Java方面犯了错误:
如果data
不是可读字符串或者是单字节编码而不是“平台的默认字符集” java.lang.String(byte[]) constructor将无法使用串出来的!在这种情况下,您必须在C端转换为UTF-8。您还将从平台特定编码的依赖性中解脱出来(可能会有很大不同)。
答案 1 :(得分:2)
我怀疑data
而不是trackID
。
env->SetByteArrayRegion(trackIDArray, 0, strlen(data), (const jbyte*)data);
然后你有字节,在java端可能看看它是什么编码 - 通过十六进制转储或其他检查。
随后:
String s = new String(data, "Cp1252"); // Or so.
答案 2 :(得分:2)
NewStringUTF希望您传递Modified UTF-8字符串。 你可能试图通过UTF-8。
有多种方法可以修复它: 最明显的一个是将字符串编码为在C ++中修改的UTF-8,然后再将其传递给Java。
另一种方法是将其作为字节数组传递给Java,并使用String构造函数将其从UTF-16转换。
第二种方式可能更有效,因为最终Java使用UTF-16进行字符串表示。
作为替代方法,您可以在C ++中将字符串转换为UTF-16并将其传递给期望UTF-16的newString JNI函数。
答案 3 :(得分: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'
}