Zitat von
Simon1988:
In dem Buffer werden ja alle array Elemente als JIntarray oder so gespeichert.
buffer := JIntArray(self.jvm.JniEnv.CallObjectMethod(instanc e, mid, []));
was hat aber die Funktion JIntArray da zu suchen ?
Na ja, JIntArray() ist hier keine funktion, sondern ein Cast. In Java würdest du es eher als (JIntArray)XYZ schreiben. Finde ich persönlich leichter lesbar (man kann es eben nicht mit einer Funktion verwechseln), aber egal.
Wichtig ist, dass du hier den Datentyp anpasst. Die Methode self.jvm.JniEnv.CallObjectMethod gibt dir ein JObject zurück. Dies liegt daran, dass jede Instanz ein Nachfahre von JObject sein muss.
Da Arrays in Java Klassen sind und du hier die Instanz eines Arrays bekommst, ist dieses Array also ein Nachfahre von Object (in Java, entspricht JObject in Delphi).
Nun möchtest du aber sagen, dass du ein bestimmten Typ von Objekt hast, nämlich ein Array, dazu castest du dieses einfach. Stimmt der Typ in den du castest, wird alles klappen (andernfalls gibt es einen Laufzeitfehler!)
Hier weißt du ja, dass der eigentlich Rückgabetyp ein Int-Array ist.
Zitat von
Simon1988:
und warum wird dann später nochmal alles auf der variablen p gespeichert , die glaube ich ein array Pointer ist ?!
p := PIntegerArray(self.jvm.JniEnv.GetIntArrayElements( buffer, isCopy));
Was du bekommen hast ist (wie glaube ich beim letzten mal erklärt) nur eine Referenz auf das Array. Arrays in C sind einfach keine Objekte (da C keine Objekte kennt!). Deshalb musst du dir den Teil des Arrays, den du verwenden möchtest in ein C-kompatibles Array umwandeln. Ich denke das habe ich beim letzten Mal schon erklärt. Frag einfach wenn du dort was nicht verstehst.
Jedenfalls legst du mit GetIntArrayElements eine Kopie an, die von einem C Programm verwendet werden kann.
Wie auch schon gesagt, sind in C Arrays nur Zeiger auf das erste Element.
Wenn du das Array A = [1,2,3,4,5] in C übergeben möchtest, es mit 4 Byte Werten gefüllt ist, so würdest du einfach die Adresse von A[0] übergeben (@A[0] in Delphi Syntax). Nun weißt du, dass A[i] einfach der Wert ist, der an @A[0] + (i * 4) liegt. 4 Bytes ist jedes Datum groß und bei @A[0] fängst du an.
So einfach sind dann auch schon die Zeiger hier.
Was dir GetIntArrayElements liefert ist nicht das komplette Arrays, sondern nur die Adresse @A[0]. In Delphi gibt es (anders als in C) die Möglichkeit direkt mit dyn. Arrays zu arbeiten, dass ist das was du hier siehst. Die gelieferte Adresse wird einfach gecastet (und der Datentyp dahinter als ein IntegerArray behandelt).
Danach kannst du wie mit einem normalen Array of Integer damit arbeiten. Beim Zugriff p[i] wird automatisch dereferenziert (wenn ich mich nicht irre). Jedenfalls siehst du irgendwo im Beispiel wie man auf die Elemente zugreift (sorry, gerade viel zu arbeiten).
Zitat von
Simon1988:
Zum letzten befehl
self.jvm.JniEnv.ReleaseIntArrayElements(buffer, PJInt(p), JNI_ABORT);
Welche Parameter müssen da übergeben werden. Klar erstmal der array, der im Buffer gespeichert ist. Was soll der zweite übergabewer`? das ist doch dann doppeltgemoppelt ^^. ist doch das gleiche wie der buffer nur als Pointer oder ?
Ist nicht wirklich doppelt gemoppelt. Klar, in dem Beispiel enthalten beide die gleichen Daten, aber wie gesagt, es wird dass Java Array kopiert (und dabei C konform umgewandelt). Das kostet natürlich Speicher und Zeit. Möchtest du nur einen bestimmten Teil des Arrays, so kannst du auch nur den kopieren, dafür gibt es dann eigene Funktionen in JNI. Hier hast du halt mit dem ganzen Array gearbeitet.
Nimmst du nur einen kleinen Teil, so kostet das kopieren weniger Zeit. Würdest du die Werte verändern und zurückschreiben, muss Java aber wissen, dass es nur ein kleiner Teil war den du da hast. Sagen wir du hast in Java ein Array von 10.001 Elementen und veränderst nur die letzten 10. Dann möchtest du die sicher auch wieder an die Stellen 9.990 - 10.000 schreiben. Dafür ist der zweite Parameter gut!
Hoffe ich konnte dir ein paar Fragen beantworten.