我试图将jintArray从C ++返回到Java,但应用程序似乎挂在JNI调用中。我已经把问题解决了jintArray的创建和人口问题,尽管我没有收到任何错误。任何帮助表示赞赏。
测试项目以确保一切正常:
include "stdafx.h"
include "windows.h"
include <vector>
include <iostream>
include <jni.h>
using namespace std;
std::vector<jint> childWindows;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
childWindows.push_back((jint) hwnd);
return TRUE;
}
jint* getChildWindows(HWND hWnd) {
childWindows.clear();
::EnumChildWindows(hWnd, EnumChildProc, NULL);
int len = static_cast<int>(childWindows.size());
jint values[100];
std::copy(childWindows.begin(), childWindows.end(), values);
for (std::vector<jint>::const_iterator i = childWindows.begin(); i != childWindows.end(); ++i) {
std::cout << (HWND)*i << ' ';
}
//env->SetIntArrayRegion(childeren, 0, len, values);
return values;
}
int _tmain(int argc, _TCHAR* argv[])
{
getChildWindows((HWND)1377258);
std::cout << " | Windows count: " << childWindows.size() << " ";
return 0;
}
输出:
000D0550 000B04F2 001C047A 0002055E 00020558 00010564 0007054E 00050570 00060512 000C04E0 | Windows数:10
Java代码:
System.out.println("Get child windows");
System.out.println("Main handle: " + getHandle());
final int[] handles = getChildWindows();
System.out.println("Done getting childs");
Java输出:
启动测试子窗口
获取子窗口
主要手柄:525978
JNI代码:
JNIEXPORT jintArray JNICALL Java_main_getChildWindows(JNIEnv *env, jclass c) {
childWindows.clear();
::EnumChildWindows(hWnd, EnumChildProc, NULL);
int len = static_cast<int>(childWindows.size());
jintArray childeren = env->NewIntArray(len);
jint values[100];
std::copy(childWindows.begin(), childWindows.end(), values);
env->SetIntArrayRegion(childeren, (jsize)0, (jsize)len, values);
//env->ReleaseIntArrayElements(childeren, values, 0);
return childeren;
}
答案 0 :(得分:1)
您在JNI呼叫后没有检查错误。这可能导致您不是在出现错误的位置而是在您调用JVM的下一个位置编码崩溃的情况。当发生这种情况时,你不会在任何友好的意义上得到“错误” - 你获得这些错误的机会是检查返回值并查询JVM是否有未决异常。 (见下文。)
在您的情况下,例如,如果
jintArray childeren = env->NewIntArray(len)
生成异常(在JVM中的Java中),您的代码将继续超过本机代码中的那一行,但JVM仍将保留该异常。下次调用JVM(恰好是您在设置数组值时确定的行)时,代码将崩溃。您需要明确清除异常。
在任何情况下,您都应该检查返回值并检查异常。 (请参阅ExceptionOccurred和ExceptionClear的JNI文档。)我敢打赌,由于某种原因,您未能获得分配的数组。究竟为什么会发生这种情况对我来说并不清楚你的代码,但这会给你一个具体的起点,即如果你有一个例外,或者你有一个空引用,它将为你提供有关出错的信息。它还可能会将您的搜索转移到出现问题的位置。
祝你好运!