2015-08-12 12 views
6

C++'dan Java'ya jintArray döndürmeye çalışıyorum, ancak uygulama JNI çağrısında asılı gibi görünüyor. Herhangi bir hata almadığım halde sorunu jintArray'ın oluşturulmasına ve popülasyonuna düşürdüm. Herhangi bir yardım takdir edilir. her şeyi emin olmakJNI'den geri dönen jintArray

Test projesi çalışır:

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; 
} 

Çıktı:

000D0550 000B04F2 001C047A 0002055E 00020558 00010564 0007054E 00050570 00060512 000C04E0 | , Windows saymak: 10

Java kodunu:

System.out.println("Get child windows"); 
    System.out.println("Main handle: " + getHandle()); 
    final int[] handles = getChildWindows(); 
    System.out.println("Done getting childs"); 

Java çıkışı:

Başlangıç ​​testi alt pencereleri

alın alt pencereleri

Ana sap: 525978

JNI'yı kodu: JNI'yı çağırır sonra

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

C kodu ilk bittiğinde sahip olduğunuz JNI yöntemine aynı tür izlemeyi eklemeyi düşündünüz mü? – EJP

+0

, ayrı bir iş parçacığındaki getChildWindows() öğesini çağırmayı deneyin – user2543253

cevap

1

Sen hatalara karşı kontrol etmediğinizde. Bu, hata yaptığınız noktada değil, JVM'ye girdiğiniz sonraki noktada kilitlenme yaptığınız bir duruma yol açabilir. Bu durum gerçekleştiğinde herhangi bir dostça "hata" almayacaksınız - Bunları elde etme şansınız, geri dönüş değerlerini kontrol ederek ve bekleyen istisnalar için JVM'yi sorgulayarak oldu.

jintArray childeren = env->NewIntArray(len) 

(JVM Java) oluşturduğu özel durumu kodunuzu yerel kodda bu çizginin ötesinde devam edecek, örneğin Senin durumunda

(. Aşağıya bakınız), ancak JVM Bu istisna hala devam edecek. Dizi değerlerini ayarladığınız yeri belirlediğiniz satır olan JVM'ye bir sonraki çağrıda, kod çökecektir. İstisnayı açıkça kaldırmanız gerekir.

Her durumda, dönüş değerlerini denetlemeniz ve özel durumları denetlemeniz gerekir. (ExceptionOccurred ve ExceptionClear için JNI belgelerine bakın.) Bir sebepten dolayı tahsis edilen bir dizi alamadığınız için bahse girerim. Tam olarak neden böyle bir şey sizin kodunuzdan açık değildir, fakat bu size başlamak için somut bir yer verecektir, yani bir istisnaınız varsa veya neyin ters gittiği hakkında size bilgi verecek bir null referansınız varsa. Ayrıca, aramanızı potansiyel olarak problemin oluştuğu noktaya kaydırır.

İyi şanslar!