JNI. Java Native Interface. Pratikum SWE 2 Institut für Systemsoftware, Johannes Kepler Universität Linz

Ähnliche Dokumente
JNI. Java Native Interface. Institut für Systemsoftware, Johannes Kepler Universität Linz

JNI - Java Native Interface SYSTEM SOFTWARE 1

C/C++ Library für Java by TgZero

Java Native Interface

Java Native Interface

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Java Kurs für Anfänger Einheit 5 Methoden

Das Java Native Interface

Vorkurs C++ Programmierung

Zählen von Objekten einer bestimmten Klasse

Große Übung Praktische Informatik 1

Java Native Calls. Einbinden von C Bibliotheken in Java Klassen. Prof. Dr. Nikolaus Wulff

Java Native Interface

Algorithmen und Datenstrukturen

Objektorientierte Programmierung

1 Vom Problem zum Programm

Einführung in Java. PING e.v. Weiterbildung Andreas Rossbacher 24. März 2005

Grundlagen von Python

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Testen mit JUnit. Motivation

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Applet Firewall und Freigabe der Objekte

Einführung in die Java- Programmierung

Java: Vererbung. Teil 3: super()

Javakurs 2013 Objektorientierung

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

Typumwandlungen bei Referenztypen

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Deklarationen in C. Prof. Dr. Margarita Esponda

Einführung in die Programmierung

Javakurs zu Informatik I. Henning Heitkötter

Objektorientierte Programmierung. Kapitel 12: Interfaces

Software Engineering Klassendiagramme Einführung

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Programmierkurs Java

Einführung in die C-Programmierung

Programmieren in Java

Distributed Computing Group

C# im Vergleich zu Java

Java Virtual Machine (JVM) Bytecode

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Klassendefinitionen verstehen

Dr. Monika Meiler. Inhalt

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Objektbasierte Entwicklung

Assoziation und Aggregation

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Propädeutikum. Dipl.-Inf. Frank Güttler

Innere Klassen in Java

C++-Zusammenfassung. H. Schaudt. August 18, 2005

Java Einführung Collections

Übungsblatt 3: Algorithmen in Java & Grammatiken

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

2. Semester, 2. Prüfung, Lösung

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Java Einführung Abstrakte Klassen und Interfaces

Tutorium Rechnerorganisation

3 Objektorientierte Konzepte in Java

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Klausur zur Einführung in die objektorientierte Programmierung mit Java

SEP 114. Design by Contract

JNI. Lernziele einfache und. struktu- Code bzw. aus einem. eigenen Sprache Obschon Java in Java-Programm. aber auf können.

Einführung in die Programmierung für Wirtschaftsinformatik

Modellierung und Programmierung 1

Fakultät Angewandte Informatik Lehrprofessur für Informatik

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Einführung in die C++ Programmierung für Ingenieure

Die Programmiersprache C99: Zusammenfassung

Kapitel 6. Vererbung

Kapitel 6. Vererbung

Modul 122 VBA Scribt.docx

DLLs (dynamic loaded libraries) mit MingW erstellen

Programmieren Tutorium

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Computeranwendung und Programmierung (CuP)

Einführung in Javadoc

Client-Server-Beziehungen

Java in Macro, SCL und Data Step

Native Zeichenketten (C-Strings)

Nuetzlicher Kleinkram

Anzeige des Java Error Stack in Oracle Forms

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Kapitel 6. Vererbung

IPETRONIK TESTdrive SDK V02.00

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions

Selbststudium OOP4 Auftrag

1 Polymorphie (Vielgestaltigkeit)

Der lokale und verteilte Fall

WebService in Java SE und EE

1 Native C Code in C# Umgebung mit Visual Studio 2010

Automatisierung ( Fernsteuerung ) von Excel unter Microsoft Windows Tilman Küpper (tilman.kuepper@hm.edu)

Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Einleitende Bemerkungen

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Prof. Dr. Uwe Schmidt. 21. August Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Alltagsnotizen eines Softwareentwicklers

M. Graefenhan Übungen zu C. Blatt 3. Musterlösung

Einführung in die Java- Programmierung

How-to: Webserver NAT. Securepoint Security System Version 2007nx

SEMINARARBEIT. Interkompatibilität von Programmiersprachen: Java Native Interface

Transkript:

JNI Java Native Interface JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 Institut für Systemsoftware, Johannes Kepler Universität Linz

Probleme bei nativem Code in Java Methodenaufruf Wie kann man native Methoden aus Java-Code aufrufen? Wie kann man Java-Methoden aus nativem Code aufrufen? Parameterübergabe und Rückgabewärte Wie werden Parameterwerte und Rückgabewerte übergeben Zugriff auf Java Memory Wie kann man Daten in einem Java-Objekt oder Array lesen und schreiben? Wie kann man ein Java-Objekt anlegen? Garbage Collection Wann kann ein Objekt freigegeben werden, das von nativem Code benutzt wird?

Beispiel: Native Methoden in Java-Code Class Out definiert native Methode für Ausgabe Implementierung erfolgt in einer externen Bibliothek Laden der Library mit der nativen Implementierung vor dem ersten Aufruf class Out { static { System.loadLibrary("libout"); Lädt Library mit Implementierung nativer Methoden Methode mit Keyword native (wie abstract,d.h. keine Implementierung) public static native void print(string text);

Workflow Native Methoden in Java deklarieren (in Out.java) public static native void print(string text); Java Klassen kompilieren (erzeugt Out.class) javac Out.java Header Dateien generieren (erzeugt Out.h) javah Out Header Dateien inkludieren und native Methoden implementieren (in out.c) #include "Out.h" JNIEXPORT void JNICALL Java_Out_print(JNIEnv* env, jclass clazz, jstring text) {... Nativen Code compilieren (erzeugt libout.so) Windows: libout.dll gcc -shared -fpic -I<path-to-jdk-install-dir>/include -o libout.so out.c Programmstart mit Angabe des Pfads zur nativen Library java -Djava.library.path=. Out Native Library vor dem ersten Aufruf einer native Methode laden (in Out.java) static { System.loadLibrary("libout");

JNI Headers javah generiert Header-Dateien aus kompilierten Java-Dateien /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Out */ #ifndef _Included_Out #define _Included_Out #ifdef cplusplus extern "C" { #endif /* * Class: Out * Method: print * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_Out_print (JNIEnv*, jclass, jstring); Pro native Methode in Java gibt es eine Methode im Header mit Namen: Java_<Klassenname>_<Methodenname> #ifdef cplusplus #endif #endif Macro für Library-Export Macro für C++ Calling conventions JNI Environment: Schnittstelle zur Virtuellen Maschine Klasse der Methode (bei nichtstatischen Methoden jobject (this) Parameter der Methode: Parameter werden in native Typen übersetzt

JNI Type-Mapping Java Typ JNI Typ 32-bit Typ 64-bit Typ Signatur void void void void V byte jbyte signed char signed char B short jshort short short S int jint int int I long jlong long long long J float jfloat float float F double jdouble double double D boolean jboolean unsigned char unsigned char Z char jchar unsigned short unsigned short C java.lang.object jobject * * Ljava/lang/Object; java.lang.string jstring * * Ljava/lang/String; java.lang.class jclass * * Ljava/lang/Class; java.lang.throwable jthrowable * * Ljava/lang/Throwable; java.lang.object[] jobjectarray * * [Ljava/lang/Object; int[] jintarray * * [I? jobject * * L<full-class-name>;

Weitere JNI-Typen JNI Typ Verwendung jsize jweak jvalue jfieldid jmethodid JNIEnv Array Längen Weak References Basis für alle primitiven Typen ID für Felder ID für Methoden Interface zur Java VM Typen: Typen sind definiert in jni.h Geänderte Semantik von Typen, z.b.: Precision von float und double gleiche oder größere Wertebereiche kein Java-Overflow tatsächliche Typen sind architekturabhängig! Vererbungshierarchien gleich zu Java, z.b. jstring erbt von jobject

Object Handles Jedes Objekt (jobject, jstring, ) ist nur ein Handle für ein Java-Objekt Nativer Code bekommt nie Pointer in Java Memory 3 Arten von Handles mit unterschiedlichen Lebenszeiten local global weak lebt bis der native Frame zerstört wird, in dem der Handle angelegt wurde Parameter von nativen Methoden sind immer local kann explizit mit (*env)->deletelocalref(env, obj) zerstört werden lebt über native Frame-Grenzen hinweg muss explizit erzeugt und zerstört werden (NewGlobalRef, DeleteGlobalRef) werden explizit erzeugt und zerstört (NewGlobalRef, DeleteGlobalRef) Lebenszeiten wie global aber wie WeakReferece Objekt vom Garbage Collector freigegeben, wenn keine Referenzen in Java VM existieren Handle wird dann null

Beispiel Object Handle void Java_Foo_bar(JNIEnv* env, jclass clazz, jobject obj) { static jobject last_obj = NULL; if(last_obj!= NULL) { (*env)->deleteglobalref(env, last_obj); last_obj = (*env)->newglobalref(env, obj); printf( obj %s last_obj\n, obj == last_obj? == :!= ); printf( obj is %s the same as last_obj\n, (*env)->issameobject(obj, last_obj)? indeed : not ); Output: obj!= last_obj obj is indeed the same as last_obj

Zugriff auf Java Memory: Felder Suche Klasse jclass GetObjectClass(JNIEnv*, jobject obj) jclass FindClass(JNIEnv*, char* name) Suche Feld (mit Klasse und Name) jfieldid GetFieldID(JNIEnv*, jclass clazz, char* name, char* sig) Lese / schreibe Feld Ähnlich zu Reflection <T> Get<T>Field(JNIEnv*, jobject obj, jfieldid field); void Set<T>Field(JNIEnv*, jobject obj, jfieldid field, <T> value); <T> für unterschiedliche Typen JNIEnv* env =... jobject person =... jclass clazz = (*env)->getobjectclass(env, person); jfieldid field = (*env)->getfieldid(env, clazz, "age", "I"); jint age = (*env)->getintfield(env, person, field); (*env)->setintfield(env, person, field, age + 1); (*env)->deletelocalref(clazz);

Zugriff auf Java Memory: Array 3 Zugriffsarten Elementweiser Zugriff <T> Get<T>ArrayElement(JNIEnv*, j<t>array array, jsize index) void set<t>arrayelement(jnienv*, j<t>array array, jsize index, <T> value) Regionsweiser Zugriff Get<T>ArrayRegion(JNIEnv*, j<t>array array, jsize start, jsize length, <T>* buffer) Set<T>ArrayRegion(JNIEnv*, j<t>array array, jsize start, jsize length, <T>* buffer) Arrayweiser Zugriff <T> für unterschiedliche Typen <T>* get<t>arrayelements(jnienv*, j<t>array array) void Release<T>ArrayElements(JNIEnv*, j<t>array array, <T>* elems, jint mode) 0 kopiere Elemente in array und gib Buffer frei JNI_COMMIT kopiere Elemente in array und gib Buffer nicht frei JNI_ABORT kopiere Elemente nicht zurück und gib Buffer frei

Beispiele: Zugriff auf Arrays JNIEnv* env =...; jintarray array = ; //Access each element individually for(jsize i = 0; i < (*env)->getarraylength(env, array); i++) { jint value = (*env)->getintarrayelement(env, array, i); (*env)->setintarrayelement(env, array, i, value + 1); //Access the entire array at once jint* native_array = (*env)->getintarrayelements(env, array); for(jsize i = 0; i < (*env)->getarraylength(env, array); i++) { native_array[i]++; (*env)->releaseintarrayelements(env, array, native_array, 0); //Access chunks of the array jint* chunk = (jint*) calloc(16, sizeof(jint); for(jsize i = 0; i < (*env)->getarraylength(env, array) / 16; i++) { (*env)->getintarrayregion(env, array, i*16, 16, chunk); for(int i = 0; i < 16; i++) { chunk[i]++; (*env)->setintarrayregion(env, array, i*16, 16, chunk); free(chunk);

Zugriff auf Java Memory: Strings Lesender Zugriff wie auf Arrays jsize GetStringLength(JNIEnv*, jstring string) jchar* GetStringChars(JNIEnv*, jstring string) void ReleaseStringChars(JNIEnv*, jstring string, jchar* chars) Inhalt wird nicht zurückgeschrieben! JNIEXPORT void JNICALL Java_Out_print(JNIEnv* env, jclass clazz, jstring text) { if(text!= NULL) { jsize length = (*env)->getstringlength(env, text); jchar* characters = (*env)->getstringchars(env, text); char* native_characters = calloc(length + 1, sizeof(char)); for(jsize i = 0; i < length; i++) { native_characters[i] = (char) characters[i]; //assume ASCII only native_characters[length] = '\0'; (*env)->releasestringchars(env, text, characters); printf("%s", native_characters); free(native_characters); clazz und text sind local Handles und müssen deswegen nicht explizit gelöscht werden

Aufrufe von Java aus Native-Code Suche Klasse wie bei Feldzugriff Suche Methode "(" ParamSig0 ParamSig1 ")" ReturnSig zb: "(JJ)Z" jmethodid GetMethodID(JNIEnv*, jclass clazz, char* name, char* sig) Aufruf Parameters <T> Call<T>Method(JNIEnv*, jobject thiz, jmethodid method,...) <T> CallNonvirtual<T>Method(JNIEnv*, jobject thiz, jclass clazz, jmethodid method,...) <T> CallStatic<T>Method(JNIEnv*, jclass clazz, jmethodid method,...) Spezielle Funktionen zur Objekterzeugung jobject NewObject(JNIEnv*, jclass clazz, jmethodid constructor,...) jstring NewString(JNIEnv*, jchar* chars, jsize length) j<t>array New<Type>Array(JNIEnv*, jsize length) jobject AllocObject(JNIEnv*, jclass clazz) Erzeugt Objekt ohne Konstruktor aufzurufen!

Beispiel: Aufrufe von Java aus Native-Code JNIEnv* env =...; jobject person1 =...; jobject person2 =...; jclass object_class = (*env)->findclass(env, " Ljava/lang/Object"); (Object): boolean const char* sig = "(Ljava/lang/Object;)Z"; jmethodid equals_method = (*env)->getmethodid(env, object_class, "equals", sig); jboolean equals = (*env)->callbooleanmethod(env, person1, equals_method, person2); (*env)->deletelocalref(env, object_class); boolean equals(object)

Exceptions JNIEXPORT void JNICALL Java_Person_raiseSalary (JNIEnv* env, jclass clazz, jobject person, jdouble factor) { if(person == NULL) { char* exception_name = "java/lang/nullpointerexception"; jclass exception_class = (*env)->findclass(env, exception_name); (*env)->thrownew(env, exception_class, person must not be null ); return;... ThrowNew wirft Exception in Java VM erst, wenn die native Methode beendet ist!

Weitere JNI-Methoden Methode ExceptionOccurred ExceptionDescribe IsSameObject IsInstanceOf Beschreibung Prüft, ob der zuletzt ausgeführte Aufruf eine Exception ausgelöst hat Erzeugt einen String, der die Exception beschreibt Prüft Objekte auf Referenzgleichheit Prüft, ob ein Objekt von einem bestimmten Typ ist http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html

Zusammenfassung JNI ermöglich native Code in Java einzubinden Für jeden Java-Typ gibt es einen nativen JNI-Typ Nativer Code kann Java-Objekte benutzen und Java-Methoden aufrufen Nativer Code bekommt nie einen direkten Pointer auf Java Memory Manuelle Speicherverwaltung bei Java-Objekten (Gefahr von Memory Leaks!)