使用JNI从本机方法返回null

14 c++ java java-native-interface

我有一些本机代码返回一个jbyteArray(所以在Java端的字节[]),我想返回null.但是,如果我只是返回0代替jbyteArray,我会遇到问题.

更多信息:主要逻辑是Java,本机方法用于将一些数据编码为字节流.不要问......必须这样做.最近,本机代码不得不改变一点,现在它运行得非常糟糕.经过一些实验,包括在返回之前注释掉本机方法中的所有代码,结果是返回0会导致减速.返回实际的jbyteArray时,一切都很好.

我的代码的方法签名:

在C++方面:

extern "C" JNIEXPORT jbyteArray JNICALL Java_com_xxx_recode (JNIEnv* env, jclass java_this, jbyteArray origBytes, jobject message)
Run Code Online (Sandbox Code Playgroud)

在Java方面:

private static native byte[] recode(byte[] origBytes, Message message);
Run Code Online (Sandbox Code Playgroud)

本机代码看起来像这样:

jbyteArray javaArray;
if (error != ERROR) {
    // convert to jbyteArray
    javaArray = env->NewByteArray((jsize) message.size);
    env->SetByteArrayRegion(java_array, 0, message.size, reinterpret_cast<jbyte*>(message.buffer()));
    if (env->ExceptionOccurred()) {
        env->ExceptionDescribe();
        error = ERROR;
    }
}
if (error == ERROR) {
    return 0; // Does NOT work - doesn't crash, just slows everything down horrible.
}
else {
    return javaArray; // Works perfectly.
}
Run Code Online (Sandbox Code Playgroud)

有谁知道这可能发生的任何原因?从本机方法返回NULL代替jbyteArray是有效的,还是有另一个将null返回给Java的过程.不幸的是,我在谷歌上没有运气.

谢谢!

编辑:添加了其他信息.

Shl*_*blu 5

这是一个老问题,但我在一分钟前就提出了……

您在问题中说:

return 0; // Does NOT work - doesn't crash, just slows everything down horrible.
Run Code Online (Sandbox Code Playgroud)

我实际上只是尝试了一下,jintArray因为这是我的代码必须分配并返回的内容,除非发生错误(由与该主题无关的某些标准定义),在这种情况下它必须返回空结果。

碰巧返回NULL(定义为((void*)0))工作完美,并且被解释为null返回Java端。我没有发现演出有任何下降。除非我错过了什么回来0没有void *投不会改变任何事情了这一点。

因此,我认为这不是您遇到的速度下降的原因。NULL看起来很好回来null

编辑

  • 我确认,返回值与表演无关。我只是测试了相同的代码,该代码的一侧返回空值,而另一方则返回一个对象(a jintArray)。对于NULLjintArray大小为0 jintArray的a 和静态分配的几KB 的随机数,性能相似。

  • 我还尝试了更改调用方类的字段的值,并以大致相同的性能重现了void。速度稍慢一点,可能是由于需要捕获该字段并对其进行设置的反射代码。

  • 所有这些测试都是在Android下进行的,而不是在Java独立环境下进行的-也许这是为什么?(看评论):

    • 在HAXM下运行的API 17 x86模拟器
    • 一个API 19,在相同条件下运行
    • 在Dalvik下运行的两个API 19物理设备(一个Asus平板电脑和一个Galaxy 5)。


xto*_*ofl 0

您的代码中存在一些不对称性,这引起了我的注意:您永远不会决定要返回的对象类型,除非返回“无”。显然,env对象决定如何分配 a javaSrray,那么为什么不要求它返回某种空数组呢?在 jni 和 java 之间进行封送时,您返回的 0 可能需要以特殊方式处理。