从JNI返回jintArray

时间:2015-08-12 23:01:03

标签: java c++ java-native-interface

我试图将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;
}

1 个答案:

答案 0 :(得分:1)

您在JNI呼叫后没有检查错误。这可能导致您不是在出现错误的位置而是在您调用JVM的下一个位置编码崩溃的情况。当发生这种情况时,你不会在任何友好的意义上得到“错误” - 你获得这些错误的机会是检查返回值并查询JVM是否有未决异常。 (见下文。)

在您的情况下,例如,如果

jintArray childeren = env->NewIntArray(len)

生成异常(在JVM中的Java中),您的代码将继续超过本机代码中的那一行,但JVM仍将保留该异常。下次调用JVM(恰好是您在设置数组值时确定的行)时,代码将崩溃。您需要明确清除异常。

在任何情况下,您都应该检查返回值并检查异常。 (请参阅ExceptionOccurred和ExceptionClear的JNI文档。)我敢打赌,由于某种原因,您未能获得分配的数组。究竟为什么会发生这种情况对我来说并不清楚你的代码,但这会给你一个具体的起点,即如果你有一个例外,或者你有一个空引用,它将为你提供有关出错的信息。它还可能会将您的搜索转移到出现问题的位置。

祝你好运!