46
EDV2 - 02 - JavaNativeInterface 1 Das Java Native Interface

Das Java Native Interface

  • Upload
    svein

  • View
    89

  • Download
    1

Embed Size (px)

DESCRIPTION

Das Java Native Interface. Wozu JNI?. Man benötigt Plattform-spezifische Features, die nicht durch die vorhandenen JAVA-Klassen bereitgestellt werden. Z.B.: Zugriff auf einen Bandroboter über die SCSI-Schnittstelle um eine grafische Oberfläche zur Bedienung des Roboters zu entwickeln. - PowerPoint PPT Presentation

Citation preview

Page 1: Das Java Native Interface

EDV2 - 02 - JavaNativeInterface 1

Das Java Native Interface

Page 2: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

2

Wozu JNI?Man benötigt Plattform-spezifische Features, die nicht durch die vorhandenen JAVA-Klassen bereitgestellt werden. Z.B.:

Zugriff auf einen Bandroboter über die SCSI-Schnittstelle um eine grafische Oberfläche zur Bedienung des Roboters zu entwickeln.

Es ist eine Bibliothek mit Routinen vorhanden, die nicht in JAVA programmiert wurden. Z.B.:

Ausnutzung einer speziellen Hardware für numerische Berechnungen.

Ein kleiner zeitkritischer Programmabschnitt soll in einer hardwarenahen Sprache programmiert werden, um das Programm zu beschleunigen. Z.B.:

Textsuche in einem Editor

Skalarprodukt in einem numerischen Programm

Dreiecksberechnung in einem FEM-Code

Page 3: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

3

Was bietet JNI?Erzeugen, Analysieren und Verändern von JAVA-Objekten (einschließlich Felder und Zeichenketten) in C-Programmen.

Aufruf von JAVA-Methoden in C-Programmen.

Erzeugen und Abfangen von JAVA-Ausnahmen in C-Programmen.

Laden von JAVA-Klassen in C-Programmen.

Konsequente Typprüfung.

Page 4: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

4

Aufruf von C-Routinen aus JAVADas Java Native Interface ermöglicht die Verbindung zwischen Programmen, die in JAVA geschrieben wurden mit Programmen, die in anderen Sprachen geschrieben sind, z.B. C, C++, Assembler, FORTRAN u.s.w.

Ziele:

Die strenge Schnittstellenprüfung von JAVA soll erhalten bleiben.

Es soll ermöglicht werden aus den anderen Sprachen heraus• JAVA-Objekte zu lesen und zu erzeugen,• JAVA-Methoden aufzurufen und• JAVA-Ausnahmen zu erzeugen.

Probleme:

Unterschiede bei den primitiven Datentypen

Unterschiede bei Objekttypen

Unterschiede bei der Parameterübergabe

Es werden eine Reihe von Tools zu Verfügung gestellt, die die Kopplung zwischen JAVA und C bzw. C++ vereinfachen.

Page 5: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

5

HelloWorld: aufzurufendes C-Programm#include <stdio.h>void helloWorld(){

printf("Hello, world!\n");}

Das Programm helloWorld sei vorgegeben und als Header-File hello.h sowie als Objektlibrary (LIB) hello.lib gespeichert.

Problem:

Wie kann helloWorld in einem JAVA-Programm aufgerufen werden.

Lösung:

Entwickeln einer Schnittstelle, die in einer oder mehreren JAVA-Klassen realisiert ist und den komfortablen Zugriff auf die Library ermöglicht.

Page 6: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

6

Struktur

hello.c

C_hello.dll

Hello.java Hello.class

HelloWorld.java HelloWorld.class

hello.lib

hello.h

C_hello.c

C_hello.h

Page 7: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

7

Aufrufendes JAVA-Programm

public class Hello

{

public static native void helloWorld();

static

{

System.loadLibrary("C_hello");

}

}

Page 8: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

8

Das Tool javahDas Tool javah dient dazu aus einem JAVA-Programm, das native-Methoden enthält, das header-File zu erzeugen, das die Schnittstelle zum Interface-Programm beschreibt.

Aufruf: javah –o h-file.h filename

Es wird ein header-File filename.h erzeugt, das die zu realisierenden Schnittstellen beschreibt.

Beispiel: javah -o C_hello.h Hello erzeugt C_hello.h

Page 9: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

9

Erzeugtes header-File C_Hello.h/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class Hello */

#ifndef _Included_Hello#define _Included_Hello#ifdef __cplusplusextern "C" {#endif/* * Class: Hello * Method: helloWorld * Signature: ()V */JNIEXPORT void JNICALL Java_Hello_helloWorld (JNIEnv *, jclass);

#ifdef __cplusplus}#endif#endif

Page 10: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

10

Ausfüllen der SchnittstelleEs ist nun das Interface zu programmieren.

Dazu muss das in dem Header-File definierte Programm Java_Hello_helloWorld programmiert werden.

Die Parameter können zunächst vernachlässigt werden.

#include "C_hello.h"

/*

* Class: Hello

* Method: helloWorld

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_Hello_helloWorld (JNIEnv * env, jclass class)

{

helloWorld();

}

Page 11: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

11

Übersetzen des C-InterfacesBei der Übersetzung muss die Library hello.dll eingebunden werden:hello.lib

Es müssen die JNI-spezifischen Include-Verzeichnisse angegeben werden:-Ic:\jdk1.3\include -Ic:\jdk1.3\include\win32

Es muss eine DLL erzeugt werden:-LD -FeC_hello.dll

Insgesamt für MS-C-Compiler unter Windows:cl -Ic:\jdk1.3\include -Ic:\jdk1.3\include\win32 C_hello.c hello.lib -LD -FeC_hello.dll

Page 12: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

12

Nutzung des InterfacesDas so entwickelte Interface kann nun wie eine ganz normale JAVA-Klasse verwendet werden.

public class HelloWorld

{

public static void main(String[] args)

{

Hello.helloWorld();

}

}

Page 13: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

13

Übergabe von ParameternProblem: Datentypen von JAVA und C sind nicht kompatibel.

C-Datentypen sind nicht vollständig standardisiert und damit abhängig von Compiler, Betriebssystem und Hardware.

JAVA-Datentypen sind vollständig standardisiert und überall identisch.

Der Zugriff auf Attribute von Parameter-Objekten ist naturgemäß recht kompliziert.

Page 14: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

14

Beispiel: EchoText

#include <stdio.h>

void helloWorld()

{

printf("Hello, world!\n");

}

void echoText(const char *text)

{

printf("%s\n",text);

}

Page 15: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

15

Header-File:C_hello.hZusätzlich wird folgender Text generiert.

Er enthält einen zusätzlichen Parameter vom Typ jstring.

Problem: dieser Parameter muss in eine Zeichenkette vom C-Typ char* umgewandelt werden.

/*

* Class: Hello

* Method: echoText

* Signature: (Ljava/lang/String;)V

*/

JNIEXPORT void JNICALL Java_Hello_echoText

(JNIEnv *, jclass, jstring);

Page 16: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

16

Lesen des ParametersProblem: Umwandlung des JAVA-String-Parameters in ein entsprechendes C-Format (const char *).

JNI stellt dafür diverse Methoden zur Verfügung.

Die Methoden sind erreichbar

in C: (*env)->Funktionsname(env,parameter);

In C++: env->Funktionsname(parameter);

Speziell lesen einer Unicode-Zeichenkette:GetStringUTFChars(env, text, isCopy)

Alle mit (*env)->GetXXXX angelegten C-Objekte müssen mit (*env)->ReleaseXXXX wieder freigegeben werden, wenn sie nicht mehr benötigt werde.

Page 17: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

17

BeispielJNIEXPORT void JNICALL Java_Hello_echoText (JNIEnv

*env, jclass class, jstring text)

{

const char *ctext;

ctext= (*env)->GetStringUTFChars(env, text, NULL);

echoText(ctext);

(*env)->ReleaseStringUTFChars(env, text, ctext);

}

Page 18: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

18

Erzeugen von JAVA-StringsZum Erzeugen eines JAVA-Strings aus einer C-Zeichenkette gibt es die Methodejstring NewStringUTF(JNIEnv *env, const char *bytes);

Achtung: Nicht vergessen, die im C-Teil reservierten Speicher freizugeben.

Page 19: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

19

Beispiel: concatSrings

char *concatStrings(const char *s1, const char *s2)

{

char *s;

s=(char *)malloc(strlen(s1)+strlen(s2)+1,sizeof(s[0]));

strcpy(s,s1);

strcat(s,s2);

return s;

}

Page 20: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

20

Hello.java

public class Hello

{

public static native void helloWorld();

public static native void echoText(String text);

public static native String concatStrings(String s1, String s2);

static

{

System.loadLibrary("C_hello");

}

}

Page 21: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

21

C_hello.h

/*

* Class: Hello

* Method: concatStrings

* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_Hello_concatStrings

(JNIEnv *, jclass, jstring, jstring);

Page 22: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

22

C_hello.c/*

* Class: Hello

* Method: concatStrings

* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_Hello_concatStrings (JNIEnv *env, jclass class, jstring s1, jstring s2)

{

const char *cs1;

const char *cs2;

char *cs;

jstring s;

cs1= (*env)->GetStringUTFChars(env, s1, NULL);

cs2= (*env)->GetStringUTFChars(env, s2, NULL);

cs = concatStrings(cs1, cs2);

(*env)->ReleaseStringUTFChars(env, s1, cs1);

(*env)->ReleaseStringUTFChars(env, s2, cs2);

s=(*env)->NewStringUTF(env, cs);

free(cs);

return s;

}

Page 23: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

23

Zugriffsmethoden für ZeichenkettenC-ASCII-Zeichenkette JAVA-Zeichenkette

jstring NewStringUTF(JNIEnv *env, const char *bytes)const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)jsize GetStringUTFLength(JNIEnv *env, jstring string)

C-Unicode-Zeichenkette JAVA-Zeichenkettejstring NewString (JNIEnv *env, const jchar *bytes)const jchar* GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy)void ReleaseStringChars(JNIEnv *env, jstring string, const jchar *utf)jsize GetStringLength(JNIEnv *env, jstring string)

Page 24: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

24

Zugriff auf FelderWie für Zeichenketten gibt es für alle Arten von eindimensionalen Feldern entsprechende New-, Get-, Set- und Release-Methoden.

Dabei muss unterschieden werden zwischen den Zugriffsmethoden für Felder von primitiven Typen und Felder von Objekten.

jsize GetArrayLength(JNIEnv *env, jarray array)bestimmt die Länge des Feldes (array.length).

<ArrayType> New<PrimitiveType>Array(JNIEnv *env, jsize length) bzw.jarray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)erzeugt ein neues Feld

Page 25: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

25

Felder umkopieren<NativeType> *Get<PrimitiveType>ArrayElements (JNIEnv *env, <ArrayType> array, jboolean *isCopy)erzeugt ein C-Feld und kopiert ggf. den Inhalt des JAVA-Feldes in das C-Feld. Änderungen des C-Feldes werden ggf. erst bei dem entsprechenden Release-Aufruf zurückkopiert. isCopy liefert JNI_TRUE, wenn das Feld kopiert wurde, JNI_FALSE sonst.

void Release<PrimitiveType>ArrayElements(JNIEnv *env, <ArrayType> array, <NativeType> *elems, jint mode)das C-Feld wird ggf. auf das JAVA-Feld zurückkopiert und die Ressourcen werden wieder freigegeben.mode steuert die Funktionen:

0 : Kopieren der Daten und Ressourcen freigeben

JNI_COMMIT : Kopieren der Daten und Ressourcen nicht freigebenJNI_ABORT : Ressourcen freigeben und Daten nicht kopieren

Page 26: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

26

Teile von Feldern umkopieren

void Get<PrimitiveType>ArrayRegion(JNIEnv *env, <ArrayType> array, jsize start, jsize len, <NativeType> *buf)kopiert die Elemente start,...,start+len-1 aus dem JAVA-Feld array in das C-Feld buf

void Set<PrimitiveType>ArrayRegion(JNIEnv *env, <ArrayType> array, jsize start, jsize len, <NativeType> *buf)kopiert die Elemente start,...,start+len-1 aus dem C-Feld buf in das JAVA-Feld array

Page 27: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

27

Elemente von Object-Arraysjobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)liest ein Element aus eine Object-Array

void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value)schreibt das Element value in das Feld

Page 28: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

28

JAVA-Typen / C-Typen

JAVA Feldtyp PrimitiveType NativeType ArrayType

boolean[] Boolean jboolean jbooleanArray

byte[] Byte jbyte jbyteArray

char[] Char jchar jcharArray

short[] Short jshort jshortArray

int[] Int jint jintArray

long[] Long jlong jlongArray

float[] Float jfloat jfloatArray

double[] Double jdouble jdoubleArray

Page 29: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

29

Beispiel : matrixXvectorvoid matrixXvector(int n, int m, double *matrix,

double *vector, double *result)

{

int i,j;

for (i=0;i<m;i++)

{

result[i]=0.0;

for (j=0;j<n;j++)

{

result[i]+=matrix[i*n+j]*vector[j];

}

}

}

Page 30: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

30

C_hello.h

/*

* Class: Hello

* Method: matrixXvector

* Signature: ([[D[D)[D

*/

JNIEXPORT jdoubleArray JNICALL Java_Hello_matrixXvector

(JNIEnv *, jclass, jobjectArray, jdoubleArray);

Page 31: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

31

C-hello.cJNIEXPORT jdoubleArray JNICALL Java_Hello_matrixXvector

(JNIEnv *env, jclass clazz, jobjectArray matrix, jdoubleArray vector) {

jsize n, m, i;

jdouble *cMatrix; jdouble *cVector; jdouble *cResult;

jboolean isCopy; jdoubleArray zeile; jdoubleArray result;

n=(*env)->GetArrayLength(env, vector);

m=(*env)->GetArrayLength(env, matrix);

cVector=(*env)->GetDoubleArrayElements(env, vector, &isCopy);

cMatrix=(jdouble *)calloc(m*n,sizeof(jdouble));

for (i=0;i<m;i++){

zeile=(jdoubleArray)((*env)->GetObjectArrayElement(env, matrix, i));

(*env)->GetDoubleArrayRegion(env, zeile, 0, n, &(cMatrix[i*n]));

}

cResult=(jdouble *)calloc(m,sizeof(jdouble));

matrixXvector(n, m, cMatrix, cVector, cResult);

result=(*env)->NewDoubleArray(env, m);

(*env)->SetDoubleArrayRegion(env, result, 0, m, cResult);

free(cMatrix);

free(cResult);

(*env)->ReleaseDoubleArrayElements(env, vector, cVector, JNI_ABORT);

return result;

}

Page 32: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

32

Zugriff auf JAVA-ObjekteObjekte können als Parameter an das Interface JAVA-C übergeben werden und es soll auf die Attribute und Methoden des Objektes zugegriffen werden.

Es soll auf JAVA-Klassen und deren statische Methoden zugegriffen werden, z.B. sollen die Methoden von StrictMath im C-Programm verwendet werden.

Es sollen im C-Programm Objekte erzeugt werden, z.B. um ein Objekt als return-Wert zurückgeben zu können.

Für die Unterscheidung der überladenenMethode spielen die Signaturen eine entscheidende Rolle.

Mit Hilfe der Signaturen lassen sich Datentypen eindeutig und relativ kompakt beschreiben.

Page 33: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

33

SignaturenType Signature Java Type

Z boolean

B byte

C char

S short

I int

J long

F float

D double

V void

Lfully-qualified-class; fully-qualified-class

[type type[]

(arg-types)ret-type method type

Page 34: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

34

Beispiele für SignaturenSignatur von Feldern: Für jeden Index eine "[" anschließend die Signatur des Elementtyps.Z.B.: double[][] [[D

Signatur von Objekten: Lvoller-Klassen-Name;Z.B.: String Ljava/lang/String;

Signatur von Methoden: (Signaturen der Parameter)Signatur des Wertes.Z.B.: double[] methode(int[][], boolean)([[DZ)[D

Page 35: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

35

Zugriff auf Attribute von ObjektenAllgemeiner Typ von Objekten: jobject

Der Zugriff auf Attribute erfolgt über den FieldID. Um den FieldID zu bestimmen benötigt man:

Die Klasse zu der das Objekt gehört.

Den Namen des Attributes.

Die Signatur des Attributes.

Es muss unterschieden werden zwischen statischen und nichtstatischen Attributen und Methoden.

jclass GetObjectClass(JNIEnv *env, jobject obj)bestimmt die Klasse zu der das Objekt obj gehört.

jclass FindClass(JNIEnv *env, const char *name)bestimmt die Klasse anhand ihres vollständigen Namens

Für interne Klassen gilt der Klassenname: Klasse$interneKlasse

Page 36: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

36

nichtstatische AttributejfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)bestimmt aus der Klasse, dem Attributnamen und seiner Signatur den FieldID.

<NativeType> Get<PrimitiveType>Field(JNIEnv *env, jobject obj, jfieldID fieldID)liest den Wert des Attributes, funktioniert auch für Objekt-Typen

void Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID, <NativeType> value)schreibt einen Wert in das Attribut

Page 37: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

37

Beispiel

... method(JNIEnv *env, jclass class, jobject obj)

{

jclass objClass;

jfieldID attrID;

jint intAttr;

objClass=(*env)->GetObjectClass(env, obj);

attrID=(*env)->GetFieldID(env, class, "dimension", "I");

intAttr=(*env)->GetIntField(env, obj, attrID);

intAttr=2*intAttr+77;

(*env)->SetIntField(env, obj, attrID, intAttr);

}

Page 38: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

38

statische AttributejfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)bestimmt aus der Klasse, dem Attributnamen und seiner Signatur den FieldID.

<NativeType> GetStatic<PrimitiveType>Field(JNIEnv *env, jclass clazz, jfieldID fieldID)liest den Wert des Attributes, funktioniert auch für Objekt-Typen

void SetStatic<type>Field(JNIEnv *env, jclass clazz, jfieldID fieldID, <NativeType> value)schreibt einen Wert in das Attribut

Page 39: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

39

Beispiel

... method(JNIEnv *env, jclass class, jobject obj)

{

jclass objClass;

jfieldID attrID;

jint intAttr;

objClass=(*env)->GetObjectClass(env, obj);

attrID=(*env)->GetStaticFieldID(env, class, "dimension", "I");

intAttr=(*env)->GetStaticIntField(env, class, attrID);

intAttr=2*intAttr+77;

(*env)->SetStaticIntField(env, class, attrID, intAttr);

}

Page 40: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

40

nichtstatische Methoden von ObjektenjmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)bestimmt den MethodID einer Methode. Bei überladenen Methoden wird die sie durch die Signatur identifiziert.

Diese Varianten des Aufrufs von JAVA-Methoden unterscheiden sich nur in der Art der Übergabe der Parameter.

<NativeType> Call<PrimitiveType>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)alle Parameter werden nacheinander angegeben

<NativeType> Call<PrimitiveType>MethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)die Parameter werden als Feld übergeben

<NativeType> Call<PrimitiveType>MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)die Parameter werden als Liste übergeben

Page 41: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

41

Beispiel

method(JNIEnv *env, jclass class, jobject obj)

{

jclass objClass;

jmethodID methID;

objClass=(*env)->GetObjectClass(env, obj);

methID=(*env)->GetMethodID(env, objClass,

"setDimension", "(I)V");

(*env)->CallVoidMethod(env, obj, methID, 777);

}

Page 42: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

42

Aufruf statischer MethodenjmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)

<NativeType> CallStatic<PrimitiveType>Method (JNIEnv *env, jclass clazz, jmethodID methodID, ...)alle Parameter werden nacheinander angegeben

<NativeType> CallStatic<PrimitiveType>MethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)die Parameter werden als Feld übergeben

<NativeType> CallStatic<PrimitiveType>MethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)die Parameter werden als Liste übergeben

Page 43: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

43

Beispiel

... jdouble sin(JNIEnv *env, jclass clazz, jdouble x)

{

jclass cl;

jmethodID sinID;

jdouble sx;

cl=(*env)->FindClass(env, "java/lang/StrictMath");

sinID=(*env)->GetStaticMethodID(env, cl, "sin", "(D)D");

sx=(*env)->CallStaticDoubleMethod(env, cl, sinID, x);

return sx;

}

Page 44: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

44

Neue JAVA-Objekte erzeugenjobject AllocObject(JNIEnv *env, jclass clazz)erzeugt eine neues Objekt der Klasse clazz ohne einen Konstruktor aufzurufen

jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)

jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)

jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)erzeugt ein neues Objekt, wobei der Konstruktor mit der ID methodID und den angegebenen Parametern benutzt wird.

Als Name des Konstruktors wird "<init>" verwendet. Als Signatur für den return-Wert "V".

Bei internen Klassen ist die Parameterliste am Anfang um einen Parameter jclass zu erweitern. Diesem ist der Parameter class der C-Methode zu übergeben.

Page 45: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

45

Beispiel...jobject method(JNIEnv *env, jclass clazz)

{

jclass tsClass;

jmethodID tsConst;

jobject tsObj;

jmethodID tsAdd;

tsClass=(*env)->FindClass(env, "java/util/TreeSet");

tsConst=(*env)->GetMethodID(env, tsClass, "<init>", "()V");

tsObj=(*env)->NewObject(env, tsClass, tsConst);

tsAdd=(*env)->GetMethodID(env, tsClass, "add",

"(Ljava/lang/Object;)Z");

(*env)->CallBooleanMethod(env, tsObj, tsAdd,

(*env)->NewStringUTF(env, "Mueller"));

(*env)->CallBooleanMethod(env, tsObj, tsAdd,

(*env)->NewStringUTF(env, "Meier"));

return tsObj;

}

Page 46: Das Java Native Interface

ED

V2 - 02 - JavaN

ativeInterfa

ce

46

Das Tool javapMit javap kann man class-Files bearbeiten. Javap liefert:

Ausgabe des Byte-Codes (-c)

Tabelle der lokalen Variablen (-l)

Signaturen alle Methoden (-s)