【发布时间】:2018-11-12 14:40:18
【问题描述】:
我正在处理一个使用 JNI 将 c++ 后端库集成到 Android 项目中的项目。
我正在使用 SpannableString 类并直接从 C++ 调用 setSpan() 函数来设置样式,而无需在前端用 Java 重新运行代码。
我有一个包含如下标签(如 html)的字符串:
"这是一个测试 {is} 斜体 {ie},我们用来演示应用 功能......”显然有更多的文字。
我在 c++ 中遍历所有字符串字符并保存它们的位置/然后将斜体跨度添加到我的 SpannableString。这是我的循环的样子:
int its = 0, fns = 0, crfs = 0;
for(int i = 0; i < buff.size(); ++i){
if(buff[i] != '{')
continue;
string tmp = "";
for(int a = i + 1; a < i + 5; ++a){
if(buff[a] == '}')
break;
tmp += buff[a];
}
if(tmp == "is"){
its = i;
//start of italics.
} else if(tmp == "ie"){
//end of italic tag.
if(its == 0)
continue;
set_spannable(spannable, new_style_obj(italic), its + 4, i);
its = 0;
} else if(tmp == "fn"){
//new footnote tag.
} else if(tmp == "cf"){
//new cross reference tag.
}
}
代码编译和运行完美,但斜体的位置与 java 字符串中的位置没有直接关系。由于某种原因,它会继续增加,直到我的斜体字离它们应该在的位置不远。
我在 java 中运行了相同的循环,它运行良好:
String buff = sp.toString();
int its = 0;
for(int i = 0; i < buff.length(); ++i){
if(buff.charAt(i) != '{')
continue;
String tmp = "";
for(int a = i + 1; a < i + 5; ++a){
if(buff.charAt(a) == '}')
break;
tmp += buff.charAt(a);
}
System.out.println(tmp);
if(tmp.equals("is")){
its = i;
} else if(tmp.equals("ie")){
if(its == 0)
continue;
System.out.println("Span from " + its + " to " + i);// + //buff.substr(its + 4, (i-4) -its) + "))";
sp.setSpan(new StyleSpan(1), its + 4, i, 1);
// set_spannable(spannable, new_style_obj(italic), its, i);
its = 0;
}
}
tv.setText(sp);
有趣的是java中的字符串长度总是大于c++中的字符串长度。
我已经使用 strlen(string.c_str()) 和 string.size(); 对其进行了测试。两者都不会返回与 java 调用 string.length 相同的长度。
有人知道造成这种差异的原因以及如何解决吗?是否有在 java 中读取而不是在 c++ 中读取的字符?
提前感谢您的帮助!
更新 1:这是标签位置数据 >>
C++
Span from 26 to 36
Span from 146 to 152
Span from 466 to 473
Span from 1438 to 1445
Span from 1726 to 1733
Span from 1913 to 1920
Span from 2157 to 2167
Span from 2228 to 2239
Span from 2289 to 2299
Span from 2544 to 2555
Span from 2827 to 2834
Span from 2965 to 2972
Span from 3293 to 3300
Span from 3913 to 3920
Span from 4016 to 4023
Span from 4378 to 4385
Span from 4467 to 4474
Span from 5179 to 5195
Span from 5337 to 5344
Java
Span from 26 to 36
Span from 146 to 152
Span from 462 to 469
Span from 1426 to 1433
Span from 1710 to 1717
Span from 1897 to 1904
Span from 2139 to 2149
Span from 2208 to 2219
Span from 2269 to 2279
Span from 2520 to 2531
Span from 2803 to 2810
Span from 2939 to 2946
Span from 3265 to 3272
Span from 3877 to 3884
Span from 3980 to 3987
Span from 4340 to 4347
Span from 4427 to 4434
Span from 5129 to 5145
Span from 5285 to 5292
【问题讨论】:
-
c_str() 会将字符串计为 C 字符串,因此在第一个 \0 处停止。 size() 将返回正确的 C++ 大小。 C++ 和 JNI 字符串是否一致? (显示相同)
-
字符串与我在 c++ 中创建 SpannableString 对象时使用 c++ 字符串设置 java 字符串相同(然后通过 JNI 返回给 Java)。
-
你能检查一下 C++ 中字符串的编码吗?除非您另有说明,否则这些字符串在 java 中存储为 UTF-16。所以也许问题是你的 C++ 字符串每个字符占用一个字节,而在 java 中它需要两个。
-
作为一个快速测试,尝试在 C++ 中使用 std::wstring 看看它是否能解决您的问题。
-
@AdamZahran 在进一步测试中,u16string 解决了我的问题!感谢您的回答。如果你发布它,我会正确标记它。
标签: java android c++ java-native-interface