【问题标题】:How to return variable return value from JNI function?如何从 JNI 函数返回变量返回值?
【发布时间】:2019-08-19 04:52:24
【问题描述】:

我的 JNI 方法是:

public native int MD_GetState(int index, int result);

我的 C 函数是:

JNIEXPORT jint JNICALL Java_com_test_MD_1GetState
(JNIEnv *env, jobject obj, jint index, jint result)
{
    jint* state, errCode;
    jint ret = GetInfo(Index, state, errCode);
    if(ret != 0) {
        result = errCode;
    } else {
        result = state;
    }

    return ret;
}

GetInfo(...) 是 DLL 中的一个函数,就本问题而言,它是一个黑盒实现。我想返回 stateerrCode 的值,具体取决于此函数是否返回 0(无错误)或其他。

这是正确的方法吗,还是有更好的方法来实现?


@user207421 在我的 Java 代码中,我有以下方法:

public native int methodA(int index, int type, byte[] value);

以及对应的C函数:

JNIEXPORT jint JNICALL Java_com_test_methodA
(JNIEnv *env, jobject obj, jint index, jint type, jbyteArray array)
{
    jboolean isCopy;
    jsize len = (*env)->GetArrayLength(env, array);
    jbyte* bp = (*env)->GetByteArrayElements(env, array, &isCopy);
    if (!bp) {
        return MDR_INSUFFICIENT_RESOURCES;
    }

    jint ret = GetValueA(index, type, bp, len);
    int mode = 0;
    // if error code is returned then do not save changes
    if(ret != 0) {
        mode = JNI_ABORT;
    }
    (*env)->ReleaseByteArrayElements(env, array, bp, mode);

    return ret;
}

GetValueA(...)bp 进行了更改,我能够以相同的方式将数据返回到我的 Java 代码,所以我想它应该是一个类似的实现?


@cdhowie 根据我的文档,stateerrCode 的可能值不重叠,所以我认为可以这样实现。如果有更好的方法,请告诉我,谢谢!

【问题讨论】:

  • 你不能。 Java 是按值传递的。对result 的分配不会在调用者处看到。您必须将这两个值编码为一个返回值,或者抛出一个包含错误代码的异常,或者返回一个包含两个字段的对象。
  • 您如何区分使用这种方法的 Java 代码中的这两种情况?调用者如何知道 int 是“状态”还是“错误代码”?如果结果是错误,是不是抛出异常更合适?
  • @user207421 我已编辑问题以包含我的回复。请告诉我你的想法,谢谢!
  • @cdhowie 我已经对我的问题进行了澄清,希望它能回答你的问题!
  • @user10931326 是的,修改 数组 很好,因为它们是通过引用传递的。

标签: java-native-interface pass-by-reference


【解决方案1】:

您在这里几乎没有选择。

  1. 您可以从JNI 代码中抛出异常以防出现错误,并在Exception 中添加错误代码

看这里:http://jnicookbook.owsiak.org/recipe-No-019/

  1. 您可以创建“类似”联合。它不会是一个联合(严格意义上的),但会起到类似的作用

Java

  class RetVal {
  int index;
  int result;
}

然后,您将不得不在JNI 代码中访问此类的字段。

您将能够更新对象的值并根据需要返回(通过对象)值。

请注意,您可以在 JNI 中更改对象的状态

看这里:http://jnicookbook.owsiak.org/recipe-No-020/

  1. 您可以使用字体大小技巧

您可以返回long 而不是int。这样,您可以从两个 int 值组合您的 long 值。

int a = 1;
int b = 1;
long ret = ((long)a) << 32 | ((long)b);
  1. 您可以更改 int 值的数组

看这里:http://jnicookbook.owsiak.org/recipe-No-013/

  1. 您可以在java.util.Vector 中返回值

看这里:http://jnicookbook.owsiak.org/recipe-no-045/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2016-10-02
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多