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] Encore un problème de chargement de dll


Sujet :

Entrée/Sortie Java

  1. #1
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut [JNI] Encore un problème de chargement de dll
    Bonjour,

    J'ai un problème lors de l'interfaçage d'une dll existante avec mon code Java.
    J'ai fait le tour des topics parlant du problème, mais je n'ai pas trouvé de solution... Le problème, c'est un UnsatisfiedLinkError sur une des méthodes de la dll...


    Je décrit toutes les étapes :
    - Logiciels : Eclipse pour la partie Java - Visual Studio 6 pour la partie C++ - le tout sous Windows

    1) Ecriture du ".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
     
    public class LibraryInterface {
    	static {
    		System.loadLibrary("LibraryInterface");
    		System.out.println("dll loadée!");
    	}
     
     
    	protected ArrayList channelsList;
     
     
     
    	public LibraryInterface() {
    		channelsList = new ArrayList();
    	}
     
     
    	public boolean loadHeader(String pathname) {
    		File file = new File(pathname);
     
    		if (file.exists()) {
    			openFile(pathname);
    			return true;	
    		}
    		else {
    			return false;	
    		}
    	}
     
    	public boolean load(String pathname, int i) {
    		// on ne fait rien pour l'instant...
    		return false;
    	}
     
     
    	/** Méthodes de gestion des fichiers */
    	public native boolean openFile(String pathname);
    	public native boolean closeFile();
    	public native int getChannelsNumber();
     
    	[...]
    2) génération du ".h" :
    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
     
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class LibraryInterface */
     
    #ifndef _Included_LibraryInterface
    #define _Included_LibraryInterface
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     LibraryInterface
     * Method:    openFile
     * Signature: (Ljava/lang/String;)Z
     */
    JNIEXPORT jboolean JNICALL Java_LibraryInterface_openFile
      (JNIEnv *, jobject, jstring);
     
    /*
     * Class:     LibraryInterface
     * Method:    closeFile
     * Signature: ()Z
     */
    JNIEXPORT jboolean JNICALL Java_LibraryInterface_closeFile__
      (JNIEnv *, jobject);
     
    /*
     * Class:     LibraryInterface
     * Method:    getChannelsNumber
     * Signature: ()I
     */
    JNIEXPORT jint JNICALL Java_LibraryInterface_getChannelsNumber
      (JNIEnv *, jobject);
     
     
    [...]
     
     
    #ifdef __cplusplus
    }
    #endif
    #endif
    3) Codage du ".cpp" :
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
     
    // LibraryInterface.cpp : Defines the entry point for the DLL application.
    //
     
    #include "stdafx.h"
    #include "LibraryInterface.h"
    #include <string.h>
     
    //Déclaration des variables membre :
    RDTiffDataFile::IRDTiffDataFilePtr pRDTiffDataFile;
     
     
     
    /*********************************************************************
     * Méthodes d'accés aux données : Channels, Beams, Gates, DataGroups *
     *********************************************************************/
     
    /*
     * Méthode retournant un pointeur vers la liste de Channels.
     */
    RDTiffDefinition::IChannelsPtr getChannels() {
    	// Accés à la liste des Channels
    	RDTiffDefinition::IChannelsPtr pChannels;
    	pChannels = pRDTiffDataFile->Channels;
     
    	return pChannels;
    }
     
    /*
     * Méthode retournant le Channel numéro channelId.
     */
    RDTiffDefinition::IChannelPtr getChannel(int channelId) {
    	/*
    	// Accés à la liste des Channels
    	RDTiffDefinition::IChannelsPtr pChannels;
    	pChannels = pRDTiffDataFile->Channels;
    	*/
    	RDTiffDefinition::IChannelsPtr pChannels = getChannels();
     
    	// Accés au Channel numéro channelId
    	RDTiffDefinition::IChannelPtr pChannel;
    	pChannel = pChannels->Item[channelId];
     
    	return pChannel;
    }
     
    /*
     * Méthode retournant le Beam numéro beamId du Channel numéro channelId.
     */
    RDTiffDefinition::IBeamPtr getBeam(int channelId, int beamId) {
    	RDTiffDefinition::IChannelPtr pChannel = getChannel(channelId);
    	RDTiffDefinition::IBeamsPtr pBeams = pChannel->Beams;
    	RDTiffDefinition::IBeamPtr pBeam = pBeams->Item[beamId];
     
    	return pBeam;
    }
     
    /*
     * Méthode retournant la Gate numéro gateId du Beam numéro beamId du Channel numéro channelId.
     */
    RDTiffDefinition::IGatePtr getGate(int channelId, int beamId, int gateId) {
    	RDTiffDefinition::IBeamPtr pBeam = getBeam(channelId, beamId);
    	RDTiffDefinition::IGatesPtr pGates = pBeam->Gates;
    	RDTiffDefinition::IGatePtr pGate = pGates->Item[gateId];
     
    	return pGate;
    }
     
    /*
     * Méthode retournant le DataGroup numéro groupId de la Gate numéro gateId 
     * du Beam numéro beamId du Channel numéro channelId.
     */
    RDTiffDefinition::IDataGroupPtr getDataGroup(int channelId, int beamId, int gateId, int groupId) {
    	RDTiffDefinition::IGatePtr pGate = getGate(channelId, beamId, gateId);
    	RDTiffDefinition::IDataGroupsPtr pGroups = pGate->DataGroups;
    	RDTiffDefinition::IDataGroupPtr pGroup = pGroups->Item[groupId];
     
    	return pGroup;
    }
     
    /*********************************************************************/
     
     
     
     
     
     
     
     
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        return TRUE;
    }
     
    /*
     * Class:     LibraryInterface
     * Method:    openFile
     * Signature: (Ljava/lang/String;)Z
     */
    JNIEXPORT jboolean JNICALL Java_LibraryInterface_openFile
      (JNIEnv * env, jobject, jstring path)
    {
    	RDTiffDataAccess::IRDTiffDataPtr pRDTiffData;
     
    	HRESULT hr = pRDTiffData.CreateInstance(_uuidof(RDTiffDataAccess::RDTiffData));
     
    	if (FAILED(hr)) {
    		// Traitement de l'exception
    		printf("Erreur lors de l'ouverture du fichier : pRDTiffData.CreateInstance()");
    		throw hr;
    		return FALSE;
    	}
     
    	// This following is to get a smart pointer on a file control object.
    	pRDTiffDataFile = pRDTiffData->RDTiffDataFile;
    	hr = pRDTiffDataFile->OpenFile(env->GetStringUTFChars(path,0));
     
    	if (FAILED(hr)) {
    		// Traitement de l'exception
    		printf("Erreur lors de l'ouverture du fichier : pRDTiffDataFile->OpenFile()");
    		throw hr;
    		return FALSE;
    	}
     
    	/********************************************
            // The following is to read the channels.
            RDTiffDefinition::IChannelsPtr pChannels;
            pChannels = pRDTiffDataFile->Channels;
     
            // The following is to read the first channel
            RDTiffDefinition::IChannelPtr pChannel;
            pChannel = pChannels->Item[1];
            *********************************************/
     
        return TRUE;
    }
     
    /*
     * Class:     LibraryInterface
     * Method:    closeFile
     * Signature: ()Z
     */
    JNIEXPORT jboolean JNICALL Java_LibraryInterface_closeFile__
      (JNIEnv * env, jobject)
    {
     
    	HRESULT hr = pRDTiffDataFile->CloseFile();
     
    	if (FAILED(hr)) {
    		// Traitement de l'exception
    		printf("Erreur lors de la fermeture du fichier");
    		throw hr;
    		return FALSE;
    	}
     
        return TRUE;
    }
     
    /*
     * Class:     LibraryInterface
     * Method:    getChannelsNumber
     * Signature: ()I
     */
    JNIEXPORT jint JNICALL Java_LibraryInterface_getChannelsNumber
      (JNIEnv * env, jobject)
    {
    	printf("On va faire du getChannelNumbers()");
    	// Accés à la liste des Channels
    	RDTiffDefinition::IChannelsPtr pChannels = getChannels();
    	printf("On a fait du getChannels()");
     
    	// On retourne le nombre de Channels
    	printf("On retourne %d", pChannels->Count);
    	return pChannels->Count;
    }
     
    [...]
     
    }
    4) Génération de la dll en mode "release" via Visual Studio.

    5) Déplacement de la dll dans le répertoire racine de mon projet Java (lors de la génération, elle était dans le dossier "MyProjects" du répertoire d'install de Visual Studio)

    6) Appel de la classe chargeant la dll :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	public Reader(File file) {
    		this.setPathname(file.getPath());
    		this.setFilename(file.getName());
    		this.setExtension(FileUtilities.getExtension(file));
     
    		libraryUse = new LibraryInterface();
    		libraryUse.loadHeader(pathname);
    		cscanNb = libraryUse.getChannelsNumber();
     
    [...]
    Dans la console, j'obtiens ça :
    dll loadée!
    java.lang.UnsatisfiedLinkError: openFile
    La dll est chargée, mais la fonction n'est pas trouvée, alors que la déclaration correspond bien (enfin, si j'ai pas des yeux de taupe...)

    Quelqu'un saurait pourquoi ça ne marche pas?
    Merci d'avance!

  2. #2
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut
    J'ai vraiment du mal ou alors la signature de la méthode JNI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /*
     * Class:     LibraryInterface
     * Method:    openFile
     * Signature: (Ljava/lang/String;)Z
     */
    JNIEXPORT jboolean JNICALL Java_LibraryInterface_openFile
      (JNIEnv * env, jobject, jstring path)
    correspond bien à la déclaration de la méthode Java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public native boolean openFile(String pathname);
    ?

  3. #3
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut
    J'aime pas insister, mais c'est ultra-bloquant...
    Malgré les tutos et les topics, je ne vois pas ce qui cloche.

    Help! I need somebody! Help!

  4. #4
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut
    Bon ça y est!

    Pour ceux qui rencontreront le même problème, je vais filer la solution.

    A la base, j'appelais la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    javah -jni -classpath . MaClasse
    depuis le répertoire contenant mon MaClasse.class

    Erreeeeeuuur!!!

    Comme mon projet comporte plusieurs packages et sous-packages, ça buggait.
    En fait en se mettant dans le répertoire "bin" de mon workspace et en tapant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    javah -jni -classpath . package1.package2.package3.MaClasse
    ça me génére un fichier nommé "package1_package2_package3_MaClasse.h" dans mon répertoire "bin".
    Et c'est à partir de ce fichier qu'il faut travailler. Son nom est tout moisi, ça se répercute sur les noms des méthodes et tout le toutim, mais au moins ça fonctionne...

    Si quelqu'un connaît un moyen de contourner le problème, je suis aussi preneur.

  5. #5
    Membre du Club Avatar de Batou
    Inscrit en
    Mars 2004
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 71
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par seiryujay
    Son nom est tout moisi
    mdr

    j'ai le mm pb en ce moment, merci pour la solution!!!
    "It has to start somewhere, It has to start sometime.
    What better place than here, what better time than now?
    " [RATM]

  6. #6
    Membre averti

    Profil pro
    Chercheur en informatique
    Inscrit en
    Novembre 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 130
    Points : 392
    Points
    392
    Par défaut
    Ben maintenant on est trois à avoir ce problème

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

Discussions similaires

  1. Problème de chargement de DLL (MSVFW32.DLL)
    Par deebou dans le forum Qt Creator
    Réponses: 2
    Dernier message: 10/04/2012, 16h15
  2. [XL-2010] Version 64 bit - Problème de chargement de DLL
    Par ArnaudEIC dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 09/09/2010, 14h26
  3. Problème de chargement de dll
    Par nasbe dans le forum WinDev
    Réponses: 2
    Dernier message: 09/01/2009, 17h32
  4. Problème de Chargement de DLL
    Par coax81 dans le forum Langage
    Réponses: 7
    Dernier message: 14/10/2008, 18h13
  5. JNI - Problème de chargement de DLL
    Par indepthsight dans le forum C++
    Réponses: 1
    Dernier message: 30/11/2007, 10h19

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