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

Entrée/Sortie Java Discussion :

JNI et Plugin Eclipse: chargement d'une DLL


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut JNI et Plugin Eclipse: chargement d'une DLL
    Bonjour à tous !

    Me voici confronté à un problème sur lequel je perds mon latin ... je vous explique:


    Je souhaite utiliser une DLL en Java via JNI.

    J'ai donc crée un code de ce type:

    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
     
    class XYZ_Interface {
     
            public native String XYZ_DecodeMessage(String filePath, int nMessageTag, String pucBinary, int nBinarySize);
     
    	static {
    		System.load("C:\\skjhdsjhdjqksd\\xyz_int.dll");
    	}
     
    	public static void main(String[] args) {
     
    		String hexStr = "392E373239363032303133333330303030353032202020202020313030373031313032393030464F30303031303030301C4634323934343320201C4730393238434443361C361E453035311E493735321E513031303035374231323044453441454435303336333033301E4820301C391E41351E6F31323603";
    		System.out.println("J - Chaine encodee:\n" + hexStr);
    		System.out.println("J - Chaine recue:\n" + new XYZ_Interface().XYZ_DecodeMessage("sample.xml", 3842, hexStr, hexStr.length()));
    	}
    }
    Je compile (sous windows):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    javac XYZ_Interface.java
    Je génère le .h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    javah -jni XYZ_Interface
    Je code ma DLL que je compile comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gcc -c xyz_int.c abcdef.h XYZ_Interface.h XYZ_.h
    gcc -shared -o xyz_int.dll xyz_int.c XYZ_Interface.def -Wl,--enable-stdcall-fixup
    J'exécute le tout avec:
    et j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    J - Chaine encodee:
    392E3732393630323031333333303030303530322020202020203130303730313
     
    [...]
     
    J - Chaine reçue:
    0001000081000000000000000082810000D0EA03000000392E00810100D0EA04
     
    [...]
    Bref, l'appel à ma DLL fonctionne et j'ai bien la chaine décodée que je souhaite obtenir.

    Mais où est ton problème, mec ?
    C'est là qu' Eclipse intervient... je copie-colle la classe Java présentée ci-dessus et je l'ajoute dans mon projet.

    Je met un try/catch autour du System.load() pour récupérer les UnsatisfiedLinkError.

    Le System.load() semble bien se passer puisqu' aucune exception n'est levée, mais le code reste bloqué sur l'appel à ma fonction XYZ_Decodemessage(), si bien que dans la console je n'obtiens que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    J - Chaine encodee:
    392E3732393630323031333333303030303530322020202020203130303730313[...]
    Après avoir mis plusieurs breakpoint un peu partout, il semble que la DLL soit bien chargée, mais que le mapping de la fonction ne fonctionne pas, d'où le fait qu'il n'y ai jamais de retour.

    Comment expliquer que sans Eclipse cela fonctionne et qu'avec Eclipse le même code ne fonctionne plus ?

    Merci d'avance pour votre aide, et n'hésitez pas à me demander des précisions si besoin.


    Pour info: Eclipse v3.5.0, JDK pour la compil manuelle 1.6.0_24.

    PS: j'ai essayé de compiler une DLL qui exporte une fonction DecodeMessage() vide, mais j'ai me même problème. Il ne s'agit donc pas, à mon sens, d'un problème de la DLL.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    Bon, je progresse dans mon analyse ... et je viens de m’apercevoir que le problème vient de mon projet.

    En effet si je copie-colle le code de mon premier message dans un projet vierge, cela fonctionne. J'ai bien la réponse de ma DLL. Eclipse ne semble donc pas en cause (ça me paraissait gros).

    Mais voilà, mon projet n'est pas un simple projet, il s'agit d'un projet Plugin Eclipse. J'ai donc créé un projet plugin vierge dont je vous met l'intégralité du code ci-dessous et qui reproduit exactement le même problème.

    Je pense qu'il s'agit d'une erreur de ma part dans l'utilisation des librairies en Java dans un projet plugin, mais je ne sais pas comment m'en sortir.

    Activator.java
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    package toto;
     
    import org.eclipse.jface.resource.ImageDescriptor;
    import org.eclipse.ui.plugin.AbstractUIPlugin;
    import org.osgi.framework.BundleContext;
     
    /**
     * The activator class controls the plug-in life cycle
     */
    public class Activator extends AbstractUIPlugin {
     
    	// The plug-in ID
    	public static final String PLUGIN_ID = "toto";
     
    	// The shared instance
    	private static Activator plugin;
     
    	/**
             * The constructor
             */
    	public Activator() {
    	}
     
    	/*
    	 * (non-Javadoc)
    	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
    	 */
    	public void start(BundleContext context) throws Exception {
    		super.start(context);
    		plugin = this;
    	}
     
    	/*
    	 * (non-Javadoc)
    	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
    	 */
    	public void stop(BundleContext context) throws Exception {
    		plugin = null;
    		super.stop(context);
    	}
     
    	/**
             * Returns the shared instance
             *
             * @return the shared instance
             */
    	public static Activator getDefault() {
    		return plugin;
    	}
     
    	/**
             * Returns an image descriptor for the image file at the given
             * plug-in relative path
             *
             * @param path the path
             * @return the image descriptor
             */
    	public static ImageDescriptor getImageDescriptor(String path) {
    		return imageDescriptorFromPlugin(PLUGIN_ID, path);
    	}
    }
    SampleAction.java (voir public void run(IAction action))
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    package toto.actions;
     
    import org.eclipse.jface.action.IAction;
    import org.eclipse.jface.viewers.ISelection;
    import org.eclipse.ui.IWorkbenchWindow;
    import org.eclipse.ui.IWorkbenchWindowActionDelegate;
    import org.eclipse.jface.dialogs.MessageDialog;
     
    /**
     * Our sample action implements workbench action delegate.
     * The action proxy will be created by the workbench and
     * shown in the UI. When the user tries to use the action,
     * this delegate will be created and execution will be 
     * delegated to it.
     * @see IWorkbenchWindowActionDelegate
     */
    public class SampleAction implements IWorkbenchWindowActionDelegate {
    	private IWorkbenchWindow window;
    	/**
             * The constructor.
             */
    	public SampleAction() {
    	}
     
    	/**
             * The action has been activated. The argument of the
             * method represents the 'real' action sitting
             * in the workbench UI.
             * @see IWorkbenchWindowActionDelegate#run
             */
    	public void run(IAction action) {
    		MessageDialog.openInformation(
    			window.getShell(),
    			"Toto",
    			"Hello, Eclipse world");
     
            String hexStr = "392E37323936303230313333333030303035303220202020202031";
            System.out.println("J - Chaine encodee:\n" + hexStr);
     
            XYZ_Interface toto = new XYZ_Interface();
    		System.out.println("J - Chaine recue:\n" + toto.XYZ_DecodeMessage("c:\\sample.xml", 3842, hexStr, hexStr.length()));
            System.out.println("fin");
     
    	}
     
    	/**
             * Selection in the workbench has been changed. We 
             * can change the state of the 'real' action here
             * if we want, but this can only happen after 
             * the delegate has been created.
             * @see IWorkbenchWindowActionDelegate#selectionChanged
             */
    	public void selectionChanged(IAction action, ISelection selection) {
    	}
     
    	/**
             * We can use this method to dispose of any system
             * resources we previously allocated.
             * @see IWorkbenchWindowActionDelegate#dispose
             */
    	public void dispose() {
    	}
     
    	/**
             * We will cache window object in order to
             * be able to provide parent shell for the message dialog.
             * @see IWorkbenchWindowActionDelegate#init
             */
    	public void init(IWorkbenchWindow window) {
    		this.window = window;
    	}
    }
    XYZ_Interface.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    package toto.actions;
     
    public class XYZ_Interface {
     
     
    		   public native String XYZ_DecodeMessage(String filePath, int nMessageTag, String pucBinary, int nBinarySize);
     
    		   static {
    		      System.load("C:\\xyz_int.dll");
    		   }
    }
    Comme expliqué ci-dessus, je n'obtiens pas la réponse de la DLL, mais je n'ai aucune exception du type UnsatisfiedLinkError.

    Console:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    J - Chaine encodee:
    392E373239363032303133333330303030 [...]
    Merci d'avance pour votre aide.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    En modifiant la déclaration de ma méthode native comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public native String XYZ_DecodeMessage(String filePath, int nMessageTag, String pucBinary, int nBinarySize) throws UnsatisfiedLinkError;
    et en modifiant le code appelant de la méthode ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    String hexStr = "392E373239363032303133333 [...]";
            System.out.println("J - Chaine encodee:\n" + hexStr);
     
            String tata = "";
            try{
            	tata = toto.XYZ_DecodeMessage("c:\\test.xml", 7845, hexStr, hexStr.length());
            } catch (UnsatisfiedLinkError u) {
            	u.printStackTrace();
            	System.out.println(u.getMessage());
            }
    J'obtiens tout de même une erreur (enfin !!) :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    java.lang.UnsatisfiedLinkError: toto.actions.XYZ_Interface.XYZ_DecodeMessage(Ljava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
    	at toto.actions.XYZ_Interface.XYZ_DecodeMessage(Native Method)
    	at toto.actions.SampleAction.run(SampleAction.java:44)
    	at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:251)
    	at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:229)
    	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
    	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
    	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
    	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
    	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
    	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
    	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
    	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
    	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
    	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
    	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
    	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
    	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
    	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
    	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
    	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
    	at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
    	at org.eclipse.equinox.launcher.Main.main(Main.java:1287)
     
    [...]
     
    toto.actions.XYZ_Interface.XYZ_DecodeMessage(Ljava/lang/String;ILjava/lang/String;I)Ljava/lang/String;
    L'erreur n'est pas lancée au moment du System.load() ... mais au moment de l'utilisation de la méthode native.

    En parcourant pas mal de sites [1][2], j'ai cru comprendre, que pour un plugin Eclipse, il serait nécessaire de modifier le Manifest.MF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Bundle-NativeCode: xyz_int.dll; osname=Win32; processor=x86
    et d'ajouter la DLL au projet Eclipse (et dans Build.properties).

    Ceci est resté sans effets chez moi.

    Une idée ?

  4. #4
    Membre émérite Avatar de Lorantus
    Homme Profil pro
    Consultant développeur indépendant / Java/VB/C(++)/ObjectPal
    Inscrit en
    Août 2007
    Messages
    599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant développeur indépendant / Java/VB/C(++)/ObjectPal

    Informations forums :
    Inscription : Août 2007
    Messages : 599
    Par défaut
    Il y a beaucoup de choses...
    Tu peux reprendre de zéro ? Quel est ton probléme ? Car il y a choses que tu fais, défais et refais...
    On sait plus trop en te lisant. Reprend ton explication. Pas besoin de reprndre tout le file de ton historique... juste avec ce que tu veux, ce que tu as et ce qui t'arrive.
    Comme ça, sans forcer:
    - tu références toujours la dll en c: ?
    - Pourquoi tu la recompiles ? (si tu le fais toujours)
    - Attention au chemin lors de l'utilisation des DLL !

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Par défaut
    Bonsoir !

    Non, ce n'est pas si compliqué que cela ... je cherche juste a utiliser une DLL dans un plugin Eclipse.

    Pour ce que j'ai ? -> voir post n°2 (c'est à la lettre près ce que j'ai)
    Je devrai obtenir un message du type "Chaine reçue: ....", comme expliqué dans le post n°1.

    Quel est mon problème ?
    Comme expliqué précédemment, j'ai un code Java 100% fonctionnel qui une fois copié-collé dans un projet de plugin Eclipse ne fonctionne plus.

    Pourquoi je recompile la DLL ?
    Je ne la recompile pas à chaque fois. Dans mon premier post j'expliquai juste la méthode utilisée pour l'obtenir.
    J'ai juste fait une tentative de la recompiler en vidant la fonction exportée de son contenu pour être certain que le problème ne venait pas de la DLL elle même.

    tu références toujours la dll en c: ?
    Oui, car elle sera placée, plus tard, dans un emplacement ne figurant pas dans le path Windows. Le chemin est exact, pas de soucis de ce côté là.

    Merci de ta réponse et n'hésite pas à me redemander des précisions au besoin.

  6. #6
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    bonjour,

    La question est peut être idiote, mais as tu pensé à la mettre directement dans le jar ? Comme ça pas besoin de se poser de question sur l'endroit ou doit se trouver la ou les libs !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB] Problème de chargement d'une DLL
    Par Elijha dans le forum Windows Forms
    Réponses: 3
    Dernier message: 10/05/2006, 09h24
  2. Chargement d'une DLL
    Par olive_le_malin dans le forum MFC
    Réponses: 15
    Dernier message: 16/12/2005, 17h09
  3. Réponses: 4
    Dernier message: 03/11/2005, 13h57
  4. Contexte de chargement d'une DLL
    Par Guillemot dans le forum Windows
    Réponses: 2
    Dernier message: 10/07/2005, 09h34
  5. Chargement d'une DLL et utilisation du multithread
    Par Maitre Kanter dans le forum Langage
    Réponses: 6
    Dernier message: 07/09/2004, 23h18

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