如何从JNI函数返回变量返回值?

时间:2019-08-19 04:52:24

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

我的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的可能值不重叠,因此我认为可以以这种方式实现它。如果有更好的方法,请告诉我,谢谢!

1 个答案:

答案 0 :(得分:0)

您这里的选择很少。

  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. 您可以使用字体大小hack

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

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/