JNI jObjectArray aus jObjectArray ?

kroesi

Erfahrenes Mitglied
Hi, ich habe folgendes Problem :

Ich rufe per JNI eine C++ Methode auf, die ein jObjectArray übergeben bekommt. Soweit, so gut, funktioniert auch.

Aber :

Diese jObjectArray enthält wieder ein Array, wie lese ich das denn aus ?

Es gibt ja GetObjectArray(...), aber GetObjectArrayArray(...) eben nicht. :-)

Wenn einer weiss wie es geht, würde er mir sehr damit helfen !

Danke,

Körsi
 
  • Gefällt mir
Reaktionen: QXV
Hallo!

Verwendest du die Funktion GetObjectArrayElement? Dann bekommst du doch wieder ein jobject zurück. Hast du mal versucht dieses jobject wieder als Parameter an GetObjectArrayElement zu übergeben (ggf. vorher entsprechend Casten)?

Gruß Tom
 
Hey , danke für die schnelle Antwort, genau das habe ich probiert und es funtkioniert nicht.

Code:
jfieldID jFieldTAM_FieldDef = (*env).GetFieldID(jFieldColClass, "FieldLst", "[Lgeoarcgis/TAM_TableNames");

jobjectArray jFieldLst = (jobjectArray) (*env).GetObjectField(jFieldColClass, jFieldTAM_FieldDef);

Hier ^^ kracht es bereits ....

Krösi
 
Hallo!

Bsp.:
Java:
Code:
  /**
   * 
   */
  package de.tutorials;
  
  /**
   * @author Tom
   * 
   */
  public class NativeExample {
  
  	static {
  		System.loadLibrary("someLibrary");
  	}
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		Object[] o = new Object[] { new Object[]{ new int[] { 1, 2, 3 } }};
  		
  		nativeMethod(o);
  		
  		int[] elements = (int[]) ((Object[]) o[0])[0];
  		
  		for (int i = 0; i < elements.length; i++) {
  			System.out.println(elements[i]);
  		}
  	}
  
  	/**
  	 * wir verdoppeln die Werte des int-Arrays innerhalb des in ein Object Array
  	 * geschachtelten Object Arrays :) 
  	 * @param o
  	 */
  	private native static void nativeMethod(Object[] o);
  
  }

C++:
Code:
  // SomeLibrary.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
  //
  
  #include "stdafx.h"
  #include <iostream>
  #include "de_tutorials_NativeExample.h"
  
  using namespace std;
  
  JNIEXPORT void JNICALL Java_de_tutorials_NativeExample_nativeMethod
  (JNIEnv* env, jclass clazz, jobjectArray objectArray){
  
  	jobject firstElement = env->GetObjectArrayElement(objectArray,0);
  	
  	jobjectArray nestedObjectArray = (jobjectArray)firstElement;
  
  	jobject nestedIntArray = env->GetObjectArrayElement(nestedObjectArray,0);
  
  	jintArray intArray = (jintArray)nestedIntArray;
  	
  	jsize size = env->GetArrayLength(intArray);
  	jint *elements = env->GetIntArrayElements(intArray,false);
  
  	for(int i = 0; i < size;i++){
  		elements[i]*=2;
  	}
  
  	env->ReleaseIntArrayElements(intArray,elements,0);
  }

Ausgabe:
2
4
6


Gruß Tom
 
Wow, super, so hab ichs noch nicht probiert, aber wäre auch nicht darauf gekommen !

Vielen, vielen Dank !

So, wie du hier immer die antworten gibst, willst du nicht mal ein Buch schreiben ? :)

Werds morgen ausprobieren und dann diesen Thread auf gelöst stellen.

Krösi
 
Hmmm, ich glaube leider, mein Problem ist noch ein bisschen anders gelagert,
ich mach mal ein Beispiel.
Code:
java :

class a
{
   int zahl;
   double zahl2;
   string wort;
}

class b
{
   a arrayOfA[];
}

native void uebergebeb(b[] arrayOfB);

Darauf kann ich mit deinem Beispiel nicht zugreifen (also auf arrayOfB) .... :confused:

Oder ich mache immer noch was falsch ....

Ich habe daher den Unterschied zum Beispiel Code oben kein jIntArray, sondern ein jObjectArray(?) :
Code:
jobject firstElement = env->GetObjectArrayElement(objectArray,0);
  	
jobjectArray nestedObjectArray = (jobjectArray)firstElement;
  
jobject nestedKeinIntArray = env->GetObjectArrayElement(nestedObjectArray,0);
  
jobjectArray keinIntArray = (jObjectArray)nestedKeinIntArray; 

Will ich mir die Länges de keinIntArray holen, krachts ...

Krösi
 
Zuletzt bearbeitet:
Hallo!

Hier mal schnell ein kleines Testszenario:
Code:
  package de.tutorials;
  
  public class A {
  	public A(int zahl, double zahl2, String wort) {
  		this.zahl = zahl;
  		this.zahl2 = zahl2;
  		this.wort = wort;
  	}
  
  	int zahl;
  
  	double zahl2;
  
  	String wort;
  
  	public String toString() {
  		return wort + zahl + zahl2;
  	}
  }

Code:
  package de.tutorials;
  
  public class B {
  	public A[] arrayOfA;
  }

Code:
  package de.tutorials;
  
  public class NativeCodeExample {
  
  	static {
  		System.loadLibrary("someLib");
  	}
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		B[] arrayOfB = new B[3];
  		for (int i = 0; i < arrayOfB.length; i++) {
  			B b = arrayOfB[i] = new B();
  			A[] arrayOfA = new A[2];
  			for (int j = 0; j < arrayOfA.length; j++) {
 				arrayOfA[j] = new A(j*i,j*i,""+j+i);
  			}
  			b.arrayOfA = arrayOfA;
  		}
  		
  		someMagicNativeMethod(arrayOfB);
  		System.out.println("finish");
  	}
  	
  	public static native void someMagicNativeMethod(B[] arrayOfB);
  
  }

Code:
  JNIEXPORT void JNICALL Java_de_tutorials_NativeCodeExample_someMagicNativeMethod
    (JNIEnv *env, jclass clazz, jobjectArray objectArray){
  		 jobject firstElement = env->GetObjectArrayElement(objectArray,0);
  		 jclass objectClazz = env->GetObjectClass(firstElement);
 		 jfieldID fid = env->GetFieldID(objectClazz, "arrayOfA", "[Lde/tutorials/A;");
  		 jobject arrayOfAObject = env->GetObjectField(firstElement, fid );
  		 jobjectArray arrayOfA = (jobjectArray)arrayOfAObject;
  		 jobject firstElementOfArrayOfA = env->GetObjectArrayElement(arrayOfA,0);
 		 jclass firstElementOfArrayOfAClazz = env->GetObjectClass(firstElementOfArrayOfA);		 
 		 jfieldID wortFieldId = env->GetFieldID(firstElementOfArrayOfAClazz, "wort", "Ljava/lang/String;");
 		 jobject wortObject = env->GetObjectField(firstElementOfArrayOfA, wortFieldId );
  		 jstring wort = (jstring)wortObject;
  		 const char *str = env->GetStringUTFChars(wort, 0);
  		 cout << str << endl;
  		 env->ReleaseStringUTFChars(wort, str);
  }

Ausgabe:
00
finish

...quite easy, hu? ;-)

Gruß tom
 
Hallo Tom,

hast mir echt aus der Patsche geholfen, danke.

Nun funktioniert es endlich ! :-) :-) :-)

Krösi :-)
 
Hallo Thomas ,

ich habe dein code übernommen und ein Test programm geschrieben. Mein Test programm stürzt immer wieder ab und gibt folgende fehler

#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d895951, pid=2620, tid=1000
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-b105 mixed mode)
# Problematic frame:
# V [jvm.dll+0xd5951]
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#

--------------- T H R E A D ---------------

Current thread (0x00295c00): JavaThread "main" [_thread_in_vm, id=1000]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000009

Registers:
EAX=0x00000000, EBX=0x06b2c9d8, ECX=0x00000001, EDX=0x6d9a1e5c
ESP=0x0090fa08, EBP=0x0090fb18, ESI=0x00295ce8, EDI=0x00295c00
EIP=0x6d895951, EFLAGS=0x00010246

....

......
Stack: [0x008c0000,0x00910000), sp=0x0090fa08, free space=318k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0xd5951]
C [someLib.dll+0x114fe]
j NativeCodeExample.someMagicNativeMethod([LB;)V+0
j NativeCodeExample.main([Ljava/lang/String;)V+84
v ~StubRoutines::call_stub

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j NativeCodeExample.someMagicNativeMethod([LB;)V+0
j NativeCodeExample.main([Ljava/lang/String;)V+84
v ~StubRoutines::call_stub


..............



................

weißt du wo der Fehler liegen könnte

Gruß
 
Zurück