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