Cours Java Native Interface

Slides:



Advertisements
Présentations similaires
Speedup Prediction for Selective Compilation of Embedded Java Programs
Advertisements

La programmation orientée objet avec Java L3-MIAGE Plan
A RECUPERER EN ENTRANT Le polycopié de Caml Partie 1
Erratum C Surcharge For(int x=0; … 2.
Le mécanisme des exceptions
A propos de java Sun, fin 1995 C++ nettoyé semi-interprété
Introspection et Réflexion Manipulation dynamique de code Java.
Au programme du jour …. Ce que vous navez pas encore vu Constantes et variables de classe Main et Tests Utilisation de lAPI Existence des packages Existence.
SI3 MAM3 Hydro Nathan Cohen Igor Litovsky Christophe Papazian
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Cours MIAGE « Architectures Orientées Services » Henry Boccon-Gibod 1 Architectures Orientées Services Composants de Service Exemple pratique de développement.
MySQL I / Présentation. II / Administration et Outils.
Programmer en JAVA par Tama
LICENCE MIAGE Introduction Programmation Orientée Objet JAVA philippe
IJA - TD 2 Bases du langage
Programmation par Objets et Java
1 Une introduction à Java IFT 287 (Semaine 1). 2 Java - Historique Développé par Sun Microsystems en 1994 –Inventeur James Gosling (canadien!) Objectif.
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Olivier DERUELLE Erwan FOUYER Maxime JOUIN Rodolphe LOUE
Synchronisation et communication entre processus
Langage Oriente Objet Cours 4.
1 Guide de lenseignant-concepteur Vincent Riff 27 mai 2003.
Titre : Implémentation des éléments finis sous Matlab
Laboratoire d'Informatique de l’Université de Franche-Comté
Chapitre VII Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres.
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Classes abstraites et Interfaces
Projet poker 1/56. Introduction Présentation de léquipe Cadre du projet Enjeux Choix du sujet 2.
Introduction à la programmation (Java)
F Copyright © Oracle Corporation, Tous droits réservés. Créer des programmes avec Procedure Builder.
Langage Oriente Objet Cours 2.
66 Utilisation des classes et des objets. 6-2 Objectifs A la fin de ce cours, vous serez capables de : Créer de nouvelles classes à laide de Eclipse Utiliser.
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
Programmation concurrente
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 1 : Introduction.
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
LIFI-Java 2004 Séance du Jeudi 9 sept. Cours 1. La notion de langage Décrire une tâche à effectuer –programme Écrire à un haut niveau –facile pour lutilisateur.
COURS DE PROGRAMMATION ORIENTEE OBJET :
COURS DE PROGRAMMATION ORIENTEE OBJET :
Java, les objets : tout de suite ! Rassembler, grouper les objets
Proxy et plus Cnam Paris jean-michel Douin, douin au cnam point fr
Android View, onClick, Activity, Modèle Vue Contrôleur
99 Réutilisation du code grâce à l'héritage. 9-2 Objectifs À la fin de ce cours, vous serez capables de : Définir l'héritage Utiliser l'héritage pour.
Une introduction à Java
1111 Gestion des exceptions Objectifs À la fin de ce cours, vous serez capables de : • Expliquer les concepts de base de la gestion des exceptions.
Masters IIGLI et IGLII – Programmation générique et conception objet – – Claude Montacié 1 Cours n° 10 Interopérabilité logicielle I Entre C++
La librairie assert.h.
Traitement de différentes préoccupations Le 28 octobre et 4 novembre 2010.
1/65 微距摄影 美丽的微距摄影 Encore une belle leçon de Macrophotographies venant du Soleil Levant Louis.
Objectifs À la fin de ce cours, vous serez capables de :
1 Fichers Binaires, Accès Direct et Objets. 2 Données binaires. Il s'agit ici de lire et écrire des données binaires par opposition à du texte. Pour ce.
LES PILES ET FILES.
Notions de pointeurs en C
La notion de type revisitée en POO
Introduction à la programmation objet avec java
Cours 9 Exceptions (fin) Généricité. POO-L3 H. Fauconnier2 Chaînage d'exceptions  Une exception peut être causée par une autre.  il peut être utile.
11/04/ L'héritage Cours 7 Cours 7.
Tutorat en bio-informatique
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Schéma de conception Factory Method Exemple Sylvain Giroux.
Cours du 5 novembre.
IUT du Limousin L.U.P Michel Vergnaud Programmation Objet - Java.
Introduction au langage JAVA
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Héritage Conception par Objet et programmation Java
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 2 – Java Premiers pas Master 1 SIGLIS1 Java Lecteur - Chapitre 2 - Java Premiers Pas.
BlueJ_III 1 Java, les objets : tout de suite ! Interaction entre objets Notes de cours associées au chapitre 3 tutorial BlueJ
Transcription de la présentation:

Cours Java Native Interface Cnam Paris jean-michel Douin, version de Décembre 2004 http://jfod.cnam.fr/tp_cdi/{douin/} Notes de cours jni : de Java vers C/C++ et de C/C++ vers Java Outils utilisés : JDK1.5, Visual C++ 6.0 (utilisé en ligne de commandes) et BlueJ2.0.2

Sommaire De Java vers C/C++ De C/C++ vers Java lecture/écriture de données d'instance et de classes invocation de méthodes d'instance et de classes création d'objet création de tableaux et de String Levée et filtrage d'exceptions utilisation des moniteurs (de hoare) Entrées/sorties Série création de machine(s) Java API JNI et une analogie avec l’Architecture de la machine virtuelle

Bibliographie utilisée Le tutorial JNI de Beth Stearns http://java.sun.com/docs/books/tutorial/index.html surtout : http://java.sun.com/docs/books/tutorial/native1.1/index.html jni specification : http://java.sun.com/products/jdk/1.1/download-pdf-ps.html Un outil bien utile distribué par Sun http://www.experimentalstuff.com/Technologies/NativeCode/index.html http://www.experimentalstuff.com/data/NativeCodeIsolation1.0.tar.gz Un « essentiel » ouvrage sur le sujet Essential JNI: Java Native Interface, rob Gordon, Prentice hall.1998 ISBN 0-13-679895-0 le site de l ’éditeur http://www.phptr.com/ les instructions et l ’architecture de la machine virtuelle Java reflètent les fonctionnalités de l’ API JNI The VM specification.http://java.sun.com/docs/books/vmspec/html

JNI Pourquoi ? Applications existantes dans un environnement Java, avec ou sans les sources Programmation d ’un périphérique, logiciel de base, Entrées/Sorties, Cartes d ’acquisition, de commandes (Adressage physique, Accès au matériel, aux pilotes de la carte, interruptions… Développement en C/C++, tout en bénéficiant de l ’environnement Java IHM en Java, application en C, Applet, accès à l ’internet Code natif pour de meilleures performances en temps d ’exécution Portabilité ?

JNI Présentation Deux aspects de Java vers C/C++ de C/C++ vers Java en venant de Java ou depuis une application ordinaire L ’API JNI offre l ’accès à la machine virtuelle accès aux variables d ’instance, appel de méthodes, chargement d ’une classe, création d ’instances… Mécanisme de bas-niveau... Exceptions, Threads….

De Java vers C(jc) 1) usage du mot clé native 2) génération par les outils de SUN de l ’interface « .h » >javah -jni Exemple 3) génération de la DLL (Win32,.dll), ou de la SOL(solaris,.so) 4) exécution notes : nécessite l ’accès à $JDK_HOME\include (en fonction de la plate-forme $JDK_HOME\include\win32(ou solaris)) et l ’exécution sous DOS de C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT  Setting environment for using Microsoft Visual C++ tools.

jc) 1) Le source Java >javac JavaVersC.java public class JavaVersC { public native void bonjour(); // (1) public static void main(String args[]) { new JavaVersC().bonjour(); } static{ System.loadLibrary("VersC"); // (2) >javac JavaVersC.java (1) emploi de native (2) chargement de la librairie (DLL/sol) dans laquelle sera implémentée le code C de bonjour

jc) Le source C : interface 2) génération de l ’interface (.h) par javah >javah -jni JavaVersC /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JavaVersC */ #ifndef _Included_JavaVersC #define _Included_JavaVersC #ifdef __cplusplus extern "C" { #endif /* Class: JavaVersC * Method: bonjour * Signature: ()V */ JNIEXPORT void JNICALL Java_JavaVersC_bonjour(JNIEnv *, jobject); }

jc) le source C : Implémentation #include <stdio.h> #include "JavaVersC.h" JNIEXPORT void JNICALL Java_JavaVersC_bonjour (JNIEnv *env, jobject j){ printf("Java_JavaVersC_bonjour"); } 3) Génération de la DLL, (JavaVersC.dll) Avec visual c++ cl -I%JDK_HOME%\include -I%JDK_HOME%\win32 -LD JavaVersC.c -FeVersC.dll 4) Exécution par >java JavaVersC

jc) JNIENV et jobject JNIEnv *env jobject j En résumé Il s ’agit de l ’environnement de la machine Java associé au « Thread » courant, (le Thread ayant engendré l ’appel de la méthode native bonjour) jobject j Il s ’agit de l ’objet receveur du message bonjour(), ici l ’instance créée dans la méthode main (jclass j, dans le cas d ’une méthode de classe ) En résumé A chaque appel d ’une méthode native sont transmis par la machine Java un environnement l ’objet receveur ou la classe si c'est une méthode classe et éventuellement les paramètres

De C vers Java(cj) depuis une DLL/SO engendrée par javah emploi du mot clé native java -----native----------->C/C++ | java <----API_JNI--------- C/C++ ou depuis une application C/C++ ordinaire

cj) De C vers Java Primitives d ’accès à la machine Java <jni.h> env j <jni.h> Variables d’instance Source C Byte code class Méthodes d ’instances méthodes de classe Variables de classe

Fonctions de JNI Versions Opérations sur les classes Exceptions Références locales et globales Opérations sur les objets Accès aux champs des objets Appels de méthodes d'instances Accès aux champs statiques Appels de méthodes de classes Opérations sur les instances de type String Opérations sur les tableaux Accès aux moniteurs Interface de la JVM

cj) Accès aux Variables d'instance GetFieldID, Get<type>Field, Set<type>Field public class Exemple{ private int x; public native void setX(int val); } En C : JNIEXPORT void JNICALL Java_Exemple_setX (JNIENV *env, jobject obj, jint val){ jclass classe = (*env)->GetObjectClass(env,obj); jfieldID fid = (*env)->GetFieldID(env,classe,"x","I"); (*env)->SetIntField(env,obj,fid,val) ; instructions JVM : getfield, putfield obj x Variables d’instance

Exemple.java au complet public class Exemple{ private int x; public native void setX(int val); static{ System.loadLibrary("Exemple"); } public static void main(String args[]) { Exemple e = new Exemple(); e.setX(33); System.out.println(" dites " + e.x);

Exemple.c au complet #include "Exemple.h" JNIEXPORT void JNICALL Java_Exemple_setX(JNIEnv* env, jobject obj, jint val){ jclass cl = (*env)->GetObjectClass(env,obj); jfieldID fid = (*env)->GetFieldID(env,cl,"x","I"); (*env)->SetIntField(env,obj,fid,val) ; }

Les commandes (win32) au complet javac -classpath . Exemple.java javah -jni -classpath . Exemple cl /I%JDK_HOME%\include /I%JDK_HOME%\include\win32 /LD Exemple.c /FeExemple.dll java -cp . Exemple

Retour sur JNIENV *env env GetFieldID SetIntField GetObjectClass etc... etc... en C : (*env)->GetFieldID(env,...) en C++ : env->GetFieldID(...)

JNIENV (un extrait) typedef const struct JNINativeInterface_ *JNIEnv; void *reserved0; … jclass (JNICALL *FindClass) (JNIEnv *env, const char *name); void (JNICALL *SetIntField)(JNIEnv *env, jobject obj, jfieldID fieldID, jint val); jfieldID (JNICALL *GetFieldID)(JNIEnv *env, jclass clazz, const char *name, const char *sig);

JNIENV *env Inspiré du JRI de Netscape Chaque fonction est accessible par un déplacement fixe dans une table, Une table peut donc être substituée par une autre sans avoir à recompiler, L'implantation des fonctions de cette table est à la charge du fournisseur de la JVM, Le code C/C++ d'accès à la JVM devient portable Analogue à l'implémentation de la table des méthodes virtuelles d'une instance

cj) Accès aux Variables de classes GetStaticFieldID, GetStatic<type>Field, SetStatic<type>Field public class Exemple{ private static int x; public native void setStaticX(int val); } JNIEXPORT void JNICALL Java_Exemple_setStaticX (JNIENV *env, jobject obj, jint val){ jclass classe = (*env)->GetObjectClass(env,obj); jfieldID fid = (*env)->GetStaticFieldID(env,classe,"x","I"); (*env)->SetStaticIntField(env,classe,fid,val) ; instructions JVM : getstatic, putstatic classe x Variables de classe

cj) Appels de méthodes d ’instance obj Call<type>Method public class Exemple{ public void p(){System.out.println( "appel de p ");} public native void callP(int val); } JNIEXPORT void JNICALL Java_Exemple_callP (JNIENV *env, jobject obj){ jclass classe = (*env)->GetObjectClass(env,obj); jmethodID mid = (*env)->GetMethodID(env,classe,"p","()V"); (*env)->CallVoidMethod(env,obj,mid) ; instruction JVM : invokevirtual table des méthodes

cj) Appels de méthodes de classe CallStatic<type>Method public class Exemple{ public static void p(){System.out.println( "appel de p ");} public native void callP(int val); } JNIEXPORT void JNICALL Java_Exemple_callP (JNIENV *env, jobject obj){ jclass classe = (*env)->GetObjectClass(env,obj); jMethodID mid = (*env)->GetStaticMethodID(env, classe,"p", "()V"); (*env)->CallStaticVoidMethod(env, classe,mid) ; instruction JVM : invokestatic table des méthodes de classe

cj) Types natifs jni.h, interpreter.h,oobj.h,typecodes.h Types natifs / types java jbyte / byte, jshort / short, jint / int …. jobject / Object, jclass / Class, jstring / String, jarray / array, jthrowable / Throwable sur la palte-forme Win32 nous avons typedef jijnt long; voir fichier %JDK_HOME%\include\win32\jni_md.h

Signature des méthodes FieldType ::= BaseType | ObjectType | ArrayType BaseType B byte C char D double F float I int J long S short Z boolean ObjectType L<classname>; ArrayType [ table MethodDescriptor ::= ( FieldType *) ReturnDescriptor ReturnDescriptor ::= FieldType | V V si le type retourné est void

Signature des méthodes en "clair" >javap -s -private JavaVersC Compiled from JavaVersC.java public synchronized class JavaVersC extends java.lang.Object /* ACC_SUPER bit set */ { public native void bonjour(); /* ()V */ public static void main(java.lang.String[]); /* ([Ljava/lang/String;)V */ public JavaVersC(); static static {}; }

Objets et classe NewObject, NewObjectA,NewObjectV création d ’une instance obtention de la classe obtention du constructeur passage des paramètres et création ...//en Java : ClasseA newObj = new ClasseA(10,"hello"); jclass classe = (*env)->FindClass("ClasseA"); jMethodID mid = (*env)->GetMethodID(classe, "<init>", "(ILjava/lang/String;)V"); jint val = 10; jstring str = (*env)->NewStringUTF(env, "hello");  jobject newObj = (*env)->NewObject(env, classe,mid,val,str) ; } instruction JVM : new et invokespecial

instanceof IsInstanceOf class A{} class B extends A{void callP(boolean b){…};} ...// obj est de classe déclarée A mais constatée B jclass classeB = (*env)->FindClass("B"); if ((*env)->IsInstanceOf(obj,classeB)){ jMethodID mid = (*env)->GetMethodID(classeB, "callP", "(Z)V"); jbool val = JNI_TRUE; (*env)->CallVoidMethod(obj,mid,val) ; } instruction JVM : instanceof, (checkcast)

Tableaux et String NewObjectArray, public class Exemple{ ... public void p(){String sa = newArray(10);} public native String [] newArray(int taille); } ... jclass classe = (*env)->FindClass(env, "java/lang/String"); jObjectArray newArr = (*env)->NewObjectArray(env, taille,classe,NULL); for(int i = 0; i< taille; i++){ str = (*env)->NewStringUTF("hello");  (*env)->SetObjectArrayElement(env, newArr,i,str); (*env)->DeleteLocalRef(env, str); return newArr; DeleteLocalRef -> str a 2 références, en jni et en java (gc) instruction JVM : newarray

Objets et ramasse miettes Chaque objet crée par JNI ne peut être collecté par le ramasse miettes Java, (l'objet str est référencé dans la machine Java) DeleteLocalRef(str) // de l'exemple précédent permet de libérér cet objet (autorise la récupération mémoire par le ramasse miettes) NewGlobalRef(obj); "bloque" l'objet en mémoire

Levée d ’exceptions instruction JVM : athrow Throw ThrowNew,... JNIEXPORT void JNICALL Java_JavaVersC_bonjour (JNIEnv *env){ jclass cl; jmethodID mid; jthrowable exc; cl = (*env)->FindClass(env,"ExceptionVenantDeC"); mid = (*env)->GetMethodID(env,cl,"<init>","()V"); exc = (jthrowable)(*env)->NewObject(env,cl,mid); (*env)->Throw(env,exc); } instruction JVM : athrow

Côté Java public class ExceptionVenantDeC extends Exception{ public ExceptionVenantDeC(String msg){ super(msg); } public ExceptionVenantDeC(){} public native static void bonjour()throws ExceptionVenantDeC; /* */ { try{ ... }catch(ExceptionVenantDeC e){ e.printStackTrace();

Une variante : ThrowNew JNIEXPORT void JNICALL Java_JavaVersC_bonjour (JNIEnv *env){ jclass cl; jmethodID mid; jthrowable exc; cl = (*env)->FindClass(env,"ExceptionVenantDeC"); (*env)->ThrowNew(env,cl," appel de (*env)->ThrowNew/3 "); }

Filtrage des Exceptions en C ExceptionClear, ExceptionOccurred, ExceptionDescribe,FatalError jthrowable exc; exc = (*env)->ExceptionOccurred(env); if(exc != NULL){ // catch(Exception1 e){ …} if((*env)->IsInstanceof(env,exc,Exception1){ ……… // (*env)->ExceptionClear(); } Avec jclass Exception1 = (*env)->FindClass(env, "Exception1");

Monitor MonitorEnter, MonitorExit // l'équivalent de l'instruction synchronized (*env)->MonitorEnter(env,obj); //du code C/C++ (*env)->MonitorExit(env,obj); } instructions JVM : monitorenter, monitorexit Appels de wait et notify par les primitives GetMethodID et CallVoidMethod jclass classe = (*env)->GetObjectClass(env,obj); jMethodID waitMid = (*env)->GetMethodID(env,classe,"wait","()V"); (*env)->CallVoidMethod(env,obj,waitMid); if((*env)->ExceptionOccured()!=NULL)) // une exception est générée en Java, mauvais usage de Wait ...

Deux exemples Entrées/Sorties Voie Série Accès au « Windows Registry » …

Entrées/Sorties Voie Série Win32Port Markus Bauer, (disponible sur http://java.cnam.fr) public class Win32Port{ public native boolean open(int pnr, String par, boolean handshake); public native void clear(int pnr); public native void setTimeout(int pnr, int tout); public native int getByte(int pnr); public native int getBytes(int pnr, byte[] bytes); public native boolean putByte(int pnr, int b); public native int putBytes(int pnr, byte[] bytes); public native boolean close(int pnr); static { System.loadLibrary("portcom"); }}

Accès à la base de registres sous Windows http://www.emunix.emich.edu/~evett/ProgrammingLanguages/Core/v2ch11/Win32RegKeyTest/ Un lien à suivre … et à mettre en Oeuvre

Appel de la machine Java le source C ordinaire utilisation de javai.lib chargement et appel de la machine Java depuis le point d'entrée main le source Java ordinaire n'importe quelle application

Le source C #include <jni.h> int main(int argc, char *argv[]){ // declarations ici options[0].optionString = "-Djava.class.path=."; memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options; res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); res = JNI_CreateJavaVM(&jvm, &env, &vm_args); classe = (*env)->FindClass(env, "CVersJava"); methodeID = (*env)->GetStaticMethodID( env,classe,"main","([Ljava/lang/String;)V"); jstr = (*env)->NewStringUTF(env," depuis du c !!!"); args = (*env)->NewObjectArray( env,1,(*env)->FindClass(env,"java/lang/String"),jstr); (*env)->CallStaticVoidMethod(env,classe,methodeID,args); (*jvm)->DestroyJavaVM(jvm); } return (0);}

Le source Java public class CVersJava{ public static void main(String [] args){ System.out.println("en java dans main " + args[0]); }

Le source Complet (1) #include <jni.h> #include <stdlib.h> int main(int argc, char *argv[]){ JNIEnv *env; JavaVM *jvm; JavaVMInitArgs vm_args; JavaVMOption options[1]; jint res; jclass classe; jmethodID methodeID; jstring jstr; jobjectArray args; char classpath[1024]; options[0].optionString = "-Djava.class.path=."; options[1].optionString = "-verbose:jni"; memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options;

Le source Complet (2) res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); if (res==JNI_ERR){ printf(" erreur lors de la création de la JVM ....\n"); return 1; } classe = (*env)->FindClass(env, "CVersJava"); methodeID = (*env)->GetStaticMethodID( env,classe,"main","([Ljava/lang/String;)V"); jstr = (*env)->NewStringUTF(env," depuis du c !!!"); args = (*env)->NewObjectArray(env,1,(*env)->FindClass(env,"java/lang/String"),jstr); (*env)->CallStaticVoidMethod(env,classe,methodeID,args); (*jvm)->DestroyJavaVM(jvm); return (0); cl -I%JDK_HOME%\include -I%JDK_HOME%include\win32 SimpleHttpd.c %JDK_HOME%\lib\jvm.lib set path = %JDK_HOME\jre\bin\client\;%path% accès à jvm.dll

Un serveur Web depuis C … …. res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); if (res==JNI_ERR){ printf(" erreur lors de la création de la JVM ....\n"); return 1; } classe = (*env)->FindClass(env, "SimpleHttpd2"); methodeID = (*env)->GetStaticMethodID( env,classe,"main","([Ljava/lang/String;)V"); args = (*env)->NewObjectArray(env,0,(*env)>FindClass(env,"java/lang/String"),NULL); (*env)->CallStaticVoidMethod(env,classe,methodeID,args); return (0);

Conclusion