JNI - 将 UChar 类型映射到
我有一个 JNI 函数,它返回一个 UChar 数组(来自 ICU4C 库),我想将其转换为 Java 字符数组,以便我可以从 Java 调用它。我不确定问题出在哪里,因为每当我访问这个 JNI 函数时,一切都会崩溃并挂起,但我在任何地方都没有收到错误消息,包括在 logcat 中......非常难以调试!
UChar 数组可以直接映射到 jcharArray 类型吗?另外,我可以将它用作返回类型吗?或者我可以将其作为 JNI 函数随后填充的参数传递吗?
这是我想做的事情的一个片段:
static jint testFunction(JNIEnv* env, jclass c, jobject obj, jcharArray chsArray,
int offset, int len, jcharArray dstArray) {
jchar* dst = env->GetCharArrayElements(dstArray, NULL);
if (dst != NULL) {
UChar *str = new UChar[len];
//populate str here from an ICU4C function
for (int i=0; i<len; i++)
dst[i] = str[i]; //this might be the problematic piece of code (can I issue an assignment like this?)
}
}
env->ReleaseCharArrayElements(dstArray, dst, 0);
}
非常感谢任何帮助!
谢谢
I have a JNI function that returns a UChar array (from the ICU4C library) which I'd like to convert to a Java character array so I can call this from Java. I am not sure where the problem is as whenever I access this JNI function, everything crashes and hangs but I get no error message anywhere, including in the logcat... very difficult to debug!
Can the UChar array map directly to a jcharArray type? also, can I use it as a return type? or could I pass it in as a parameter that the JNI function then populates?
Here is a snippet of basically what I am trying to do:
static jint testFunction(JNIEnv* env, jclass c, jobject obj, jcharArray chsArray,
int offset, int len, jcharArray dstArray) {
jchar* dst = env->GetCharArrayElements(dstArray, NULL);
if (dst != NULL) {
UChar *str = new UChar[len];
//populate str here from an ICU4C function
for (int i=0; i<len; i++)
dst[i] = str[i]; //this might be the problematic piece of code (can I issue an assignment like this?)
}
}
env->ReleaseCharArrayElements(dstArray, dst, 0);
}
Any help is appreciated!
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
JNI 确实令人头疼。从表面上看,你的功能看起来很好。
首先,我注意到您没有使用 offset - 这是代码味道。
其次,您没有释放 UChar 数组。
第三,C 函数或赋值循环可能超出数组范围。
为了帮助定位像这样的突然崩溃,我成功地结合使用了一个很好的
print
语句与控制台。首先,我向 JNIGlobal 类添加了一个 println 方法:
然后,我向 C 代码添加了一个相应的方法:
然后,我只需在源代码中的每一行调用
println(env,"Some formatted output")
看看它能走多远。在我的环境(AS/400)中,当 JVM 在交互式运行期间崩溃时,我只剩下控制台 - 您可能需要在 Java 代码中添加短暂的延迟,以确保在控制台消失之前看到输出。所以对于你来说,就像这样:
JNI can be a real headache. You function looks fine, on the surface.
First, I note that you are not using
offset
- that's a code-smell.Second, you are not freeing the UChar array.
Third, either the C function or the assignment loop may be overrunning the array bounds.
To assist with locating abrupt crashes like this, I have successfully used a good-ol-fashioned
print
statement in conjunction with the console.First I added a println method to my JNIGlobal class:
Then I added a corresponding method to my C code:
Then I just call
println(env,"Some formatted output")
at each line in the source to see how far it gets. In my environment (an AS/400), when the JVM crashes during interative running I am left with the console - you might want to add a short delay in the Java code to ensure you see the output before your console goes away.So for you, like so:
如果您的目的是从 ICU 获取 UChar* 值并将字符串返回到 Java(我假设这是基于“从 ICU4C 函数在此处填充 str”注释),为什么不只使用 jstring?
例如:
该示例当然是简化的,但应该说明 UChar* 到 jstring 的转换。这也可以轻松地与 UnicodeString 一起使用:
If your intent is to get a UChar* value from ICU and return a string to Java (I'm assuming this based on the "populate str here from ICU4C function" comment), why not just use a jstring?
For example:
The example is simplifed of course, but should illustrate UChar* to jstring conversion. This also easily works with a UnicodeString:
dstArray 有多长?如果 len 大于 dstArray.length,c++ 无法检查数组边界,并且会很高兴地破坏进程的内存。
How long is the dstArray? c++ cannot check array bounds and happily corrupts the memory of your process if len is larger than dstArray.length.
ICU4JNI 并未得到积极维护,但您也许可以查看它的示例从 JNI 调用 ICU4C。另请参阅 ICU4JNI SVN 主干
ICU4JNI is not actively maintained, but you might be able to look at it for an example of calling ICU4C from JNI. See also ICU4JNI SVN trunk