JNI:将整数数组从Java传递到C

JNI:将整数数组从Java传递到C,java,c++,java-native-interface,Java,C++,Java Native Interface,编辑:请跳到第2部分以获取更简单的代码 第1部分: 我正在研究一个项目,我必须调用C++的java例程。 我使用以下代码调用java方法。该参数是一个字符串数组,前2个值用于从硬盘读取文件、解码文件并返回数据。出于测试目的,我将返回一个仅包含文件中第一个图像的1D整数数组。文件中有更多具有Z深度和时间序列的图像,就像在视频中一样,暂时忽略这些图像 mid = m_pJVMInstance->m_pEnv->GetStaticMethodID(imageJ_cls, "getI

编辑:请跳到第2部分以获取更简单的代码

第1部分: 我正在研究一个项目,我必须调用C++的java例程。 我使用以下代码调用java方法。该参数是一个字符串数组,前2个值用于从硬盘读取文件、解码文件并返回数据。出于测试目的,我将返回一个仅包含文件中第一个图像的1D整数数组。文件中有更多具有Z深度和时间序列的图像,就像在视频中一样,暂时忽略这些图像

    mid = m_pJVMInstance->m_pEnv->GetStaticMethodID(imageJ_cls, "getIntData", "([Ljava/lang/String;)[I");
    if (mid == nullptr)
        cerr << "ERROR: method not found !" << endl;
    else {
        jobjectArray arr = m_pJVMInstance->m_pEnv->NewObjectArray(2,      // constructs java array of 2
            m_pJVMInstance->m_pEnv->FindClass("java/lang/String"),    // Strings
            m_pJVMInstance->m_pEnv->NewStringUTF("str"));   // each initialized with value "str"
        m_pJVMInstance->m_pEnv->SetObjectArrayElement(arr, 0, m_pJVMInstance->m_pEnv->NewStringUTF("D:\Dev_Environment\Test_Files\\"));  // change an element
        m_pJVMInstance->m_pEnv->SetObjectArrayElement(arr, 1, m_pJVMInstance->m_pEnv->NewStringUTF("4D_1ch.lsm"));  // change an element
        jintArray depth = (jintArray)(m_pJVMInstance->m_pEnv->CallStaticIntMethod(imageJ_cls, mid, arr));   // call the method with the arr as argument.

        m_pJVMInstance->m_pEnv->DeleteLocalRef(arr);     // release the object
    }
我至少在深度变量中获得了一些值,但一旦我尝试读取这些值,就会抛出访问冲突。两行代码都会抛出错误。下面是C++代码:

jintArray depth = (jintArray)(m_pJVMInstance->m_pEnv->CallStaticIntMethod(imageJ_cls, mid, arr));
jsize len = m_pJVMInstance->m_pEnv->GetArrayLength(depth);
jint* body = m_pJVMInstance->m_pEnv->GetIntArrayElements(depth, 0);

返回int数组的工作方式与您描述的完全相同,但是调用此类Java方法的JNI函数不是CallStaticIntMethod(),而是CallStaticObjectMethod()。这是导致错误的最可能原因

要接受C中的2D数组(或更多),可以将其声明为jobjectArray,并将每个元素的对象值作为jintArray


请注意,您的C代码泄漏了一些本地引用,如果在循环中调用,这可能是一个问题。使用PushLocalFrame()和PopLocalFrame()包装此代码可能更容易。

感谢您的回复。我还有一个关于“CallStaticIntMethod”的问题。调用返回整数数组的java函数是否正确?另外,为了使您的工作更容易,如果您可以只查看java中的测试变量,它是返回的唯一变量(用于调试目的)。不过,我在C++中得到了一个0深度变量。因此,在运行此代码之后,(金t*Byth= MyPjvMeTest-> MyPeav-> GETnTayRayEngices(深度,0);)C++抛出异常。只编辑第2部分中的问题,这样就更容易理解。在第2部分中,您仍然使用错误的CaltStistCyTimeMeod()。这个调用返回一个jint,而您需要一个jobject,该jobject可能被铸造到jintArray。它必须是CallStaticObjectMethod()。
    public static int[] getIntDataS(String[] args) {
    int[] test = new int[10];
    test[0] = 10;
    test[1] = 10;
    test[2] = 10;
    test[3] = 10;
    test[4] = 10;
    test[5] = 10;
    test[6] = 10;
    test[7] = 10;
    test[8] = 10;
    test[9] = 10;
    return test;
}
jintArray depth = (jintArray)(m_pJVMInstance->m_pEnv->CallStaticIntMethod(imageJ_cls, mid, arr));
jsize len = m_pJVMInstance->m_pEnv->GetArrayLength(depth);
jint* body = m_pJVMInstance->m_pEnv->GetIntArrayElements(depth, 0);