IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Equivalent d'une fonction *.dll


Sujet :

Android

  1. #1
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut Equivalent d'une fonction *.dll
    Bonjour à toutes et à tous,

    Dans une application que j'avais développée en Pascal objet (via Delphi puis Lazarus), j'utilisais une ou plusieurs "dll" que j'attachais à mon application pour réaliser des fonctions qui n'existaient pas dans l'application de base.

    L'application et la "dll" étaient compilées indépendamment l'une de autre. La liaison ne se faisait qu'à l'exécution.

    Lors de l'exécution, si la "dll" n'était pas présente, un message m'en alertait sans pour autant que l'application plante.

    Existe-t-il un "concept" ou une "méthode" ou, je ne sais pas comment l'appeler, qui ferait la même chose.

    Cordialement.

    Pierre.

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Tu peux faire des librairie partagée via le ndk. Tu te retrouve avec des .so (equivalent du .dll de windows) créer en c ou c++ que tu peux charger dynamiquement dans ton application.
    Par contre c'est un tout autre pan de la programmation android qui est loin d'être facile à appréhender.

    Tu peux faire également la même chose directement en java avec des fichier dex. Tu as un exemple basique ici : https://stackoverflow.com/a/6860579/393984
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par grunk Voir le message
    Tu peux faire des librairie partagée via le ndk. Tu te retrouve avec des .so (equivalent du .dll de windows) créer en c ou c++ que tu peux charger dynamiquement dans ton application.
    Par contre c'est un tout autre pan de la programmation android qui est loin d'être facile à appréhender.

    Tu peux faire également la même chose directement en java avec des fichier dex. Tu as un exemple basique ici : https://stackoverflow.com/a/6860579/393984
    Cette deuxième partie me semble plus à ma portée bien que je n'ai pas trop compris comment il transformait sa classe en fichier .dex.

    A approfondir.

    Cordialement.

    Pierre.

  4. #4
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    J'essaie de mettre en œuvre l'exemple que tu m'as donné. J'ai crée un classe "ClasseEXt" comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class ClasseExt extends Activity {
     
        public ClasseExt() {
            Log.d(ClasseExt.class.getName(), "ClasseExt: constructor called.");
        }
     
        public int ajout(int a, int b) {
            return a + b;
        }
     
        public int soustrait(int a, int b) {
            return a - b;
        }
     
        public void rienfaire() {
            int a = 1 + 1;
        }
     
    }
    Je l'ai compilée, j'ai renommé le fichier apk en "fct-ext.jar" que j'ai placé dans la mémoire public de mon smartphone.

    Maintenant j'ai une application utilisatrice où j'ai écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    		try {
    			final String libPath = Environment.getExternalStorageDirectory() + "/fct-ext.jar";
    			final File tmpDir = getDir("dex", 0);
     
    			final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
    			final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.fctext.ClasseExt");
     
    			final Object myInstance  = classToLoad.newInstance();
    			final Method rienFaire = classToLoad.getMethod("rienfaire");
     
    			rienFaire.invoke(myInstance);
     
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    Je lance dette application et elle se déroule jusqu'à la fin sans problème.

    Maintenant, plutôt que de ne "rienfaire", j'essaie avec une méthode "ajout" qui accepte des paramètres en entrée et qui me retourne un résultat. J'écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    		try {
    			final String libPath = Environment.getExternalStorageDirectory() + "/fct-ext.jar";
    			final File tmpDir = getDir("dex", 0);
     
    			final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
    			final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.fctext.ClasseExt");
     
    			final Object myInstance  = classToLoad.newInstance();
    			final Method ajouter = classToLoad.getMethod("ajout");
     
    			ajouter.invoke(myInstance);
     
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    Comme je m'en doutais, ça a créé un exception à la ligne 9. J'imagine qu'il faut que j'introduise mes paramètres et que je puisse récupérer le résultat, mais je n'ai pas réussi à trouver la syntaxe pour le faire.

    Cordialement.

    Pierre.

  5. #5
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    J'ai progressé, j'arrive à donner les arguments à ma méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    		try {
    			final String libPath = Environment.getExternalStorageDirectory() + "/fct-ext.jar";
    			final File tmpDir = getDir("dex", 0);
     
    			final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
    			final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.fctext.ClasseExt");
     
    			final Object myInstance  = classToLoad.newInstance();
    			final Class[] args = new Class[2];
    			args[0] = int.class;
    			args[1] = int.class;
    			final Method ajouter = classToLoad.getMethod("ajout", args);
     
    			ajouter.invoke(myInstance, 1, 1);
     
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    Mais j'ai toujours pas trouvé comment récupérer le résultat.

    Cordialement.

    Pierre.

  6. #6
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Bon, ben ça y est, j'ai trouvé, il fallait faire un transtypage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	int res = (int) ajouter.invoke(myInstance, 1, 1);
    Cordialement.

    Pierre.

  7. #7
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Je suis etonné que ca marche en compilant un apk que tu renomme simplement en jar , mais si ca marche tant mieux.

    En théorie il faudrait faire :

    Compiler la source en bytcode (va créer un .class):
    Transformer en jar
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jar cvf Monfichier.jar Monfichier.class
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Merci "grunk" pour ces précisions. Mais ces commandes dont tu me parles, où on les trouve, où on les écrit...

    Cordialement.

    Pierre.

  9. #9
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    j'ai fait un essai temporel sur ces méthodes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    			long tMoy = 0;
    			for (int j = 0; j < 1000; j++) {
    				long tm = System.nanoTime();
    				for (int i = 0; i < 10000; i++) {
    /*					int val = 1 + 1;
    					val = 1 - 1;
    					val = 1 + 1;*/
    /*					int val = fairePlus(1, 1);
    					val = faireMoins(1, 1);
    					faireAutant();*/
    				int res = (int) ajouter.invoke(myInstance, 1, 1);
    				res = (int) soustraire.invoke(myInstance, 1, 1);
    				rienFaire.invoke(myInstance);
    				}
    				tm = (System.nanoTime() - tm) / 1000;
    				tMoy += tm;
    			}
    			tMoy /= 1000;
    			texte.setText(String.format(Locale.US, "%4d µS", tMoy));
    A l'intérieur de la boucle (for int i; ...) il y a 9 lignes :

    1. les 3 premières font un calcul direct ;
    2. les 3 suivantes font un calcul via méthodes locales ;
    3. les 3 dernières font un calcul via la classeExt.

    Je mets en œuvre successivement chaque groupe de 3 lignes :

    Les résultats sont éloquents

    1. calcul direct : tMoyen = 35 µs ;
    2. calcul via méthodes locales : tMoyen = 85 µs ;
    3. calcul via la classeExt : tMoyen = 19400 µs.


    Dans mon application de simulation temporelle ou je fais appel à un ensemble de fonctions de transfert, dont à ce genre de fonction, entre 10000 et 100000 selon la précision que je veux obtenir, j'ai l'impression que ça va mettre du temps.

    Pour autant, je n'ai jamais vérifié, dans mon application sous Windows, si le passage par les équivalents "dll" était couteux en temps.

    Je note tout simplement ici que le temps mis par ces classes Ext est vraiment couteux en temps.

    Cordialement.

    Pierre.

  10. #10
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Les commandes que je te donne sont a taper dans un terminal. javac c'est le compilateur java. Donc si tu as une installe du JDK sur ta machine c'est disponible.

    Le code ne doit pas s'executer moins vite , en revanche le chargement de ce code est plus long.
    Comme une dll , le code est natif donc aussi rapide que le code normal mais le chargement la dll peut être couteux à l'instant T
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par grunk Voir le message
    Les commandes que je te donne sont a taper dans un terminal. javac c'est le compilateur java. Donc si tu as une installe du JDK sur ta machine c'est disponible. ...
    Alors que dans Android Studio, la commande "Build --> Make Project" me fournit un fichier *.apk sans problème, la commande dans un terminal me donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    C:\Users\prcha\.jdks\openjdk-15.0.1-1\bin>javac E:\StudioProjects\FctExt\app\src\main\java\com\example\fctext\ClasseExt.java
    E:\StudioProjects\FctExt\app\src\main\java\com\example\fctext\ClasseExt.java:3: error: package android.app does not exist
    import android.app.Activity;
                      ^
    E:\StudioProjects\FctExt\app\src\main\java\com\example\fctext\ClasseExt.java:4: error: package android.util does not exist
    import android.util.Log;
                       ^
    E:\StudioProjects\FctExt\app\src\main\java\com\example\fctext\ClasseExt.java:6: error: cannot find symbol
    public class ClasseExt extends Activity {
                                   ^
      symbol: class Activity
    E:\StudioProjects\FctExt\app\src\main\java\com\example\fctext\ClasseExt.java:9: error: cannot find symbol
            Log.d(ClasseExt.class.getName(), "ClasseExt: constructor called.");
            ^
      symbol:   variable Log
      location: class ClasseExt
    4 errors
     
    C:\Users\prcha\.jdks\openjdk-15.0.1-1\bin>
    Je n'obtiens donc pas de fichier .class.

    Citation Envoyé par grunk Voir le message
    ...Le code ne doit pas s’exécuter moins vite , en revanche le chargement de ce code est plus long.
    Comme une dll , le code est natif donc aussi rapide que le code normal mais le chargement la dll peut être couteux à l'instant T
    Je me doute bien que le code s'exécute aussi vite que le code interne, mais l'accès à la fonction est alors extrêmement long si on considère que le chargement de la classe externe se fait ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
    final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.fctext.ClasseExt");
     
    final Object myInstance  = classToLoad.newInstance();
    final Class[] args = new Class[2];
    args[0] = int.class;
    args[1] = int.class;
    final Method ajouter = classToLoad.getMethod("ajout", args);
    et que son utilisation se fait ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int res = (int) ajouter.invoke(myInstance, 1, 1);
    Ça veut quand même dire que l'accès à la fonction (invoke) prend une quantité de temps incomparablement plus grande que l'exécution du code qu'elle contient.

    Est-ce que cela pourrait être dû à ma méthode d'obtention du fichier du fichier .jar juste pas changement de l'extension (la méthode que tu me proposes ne fonctionnant pas) ?

    Je viens de refaire une simulation sur 62000 points avec mon ancienne version Windows. Sans faire de mesure de temps, je n'ai pas noté de différence notable entre une fonction interne et une fonction appelée par une dll.

    Cordialement.

    Pierre.

Discussions similaires

  1. Aide pour utilisation d'une fonction DLL
    Par Hell dans le forum Langage
    Réponses: 10
    Dernier message: 22/07/2008, 10h51
  2. Equivalent d'une fonction sous 4D
    Par sscouby dans le forum 4D
    Réponses: 6
    Dernier message: 23/04/2008, 10h50
  3. [Tableaux] Equivalent d'une fonction en php
    Par Wimoux dans le forum Langage
    Réponses: 3
    Dernier message: 15/04/2008, 03h03
  4. Equivalence d'une fonction
    Par Toison dans le forum Excel
    Réponses: 2
    Dernier message: 08/04/2008, 14h38
  5. Equivalent d'une fonction en Anglais
    Par Toison dans le forum Excel
    Réponses: 5
    Dernier message: 25/01/2008, 21h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo