2011-12-07 6 views
3

J'ai cherché pendant 2 jours maintenant et aucune solution pourrait me aider, alors nous y revoilà:JNI, C++, DLL, UnsatisfiedLinkError <Native Method>

Comment fixer le UnsatisfiedLinkError ... dans JNI?

Alors, voici mon code java:

package org.lingenio.util; 

import java.util.*; 

public class PTAPIWrapperForOmegaT { 

    private native String translateWithPTAPI(String sentence); 

    private native void test(); 

    public PTAPIWrapperForOmegaT(String sentence) throws Exception{ 
     System.out.println(sentence); 
     test();  
    } 

    static { 
     System.load("C:/Users/michael/Desktop/OmegaT/OmegaT2.3_src/native/PTAPIWrapperForOmegaT.dll"); 
    } 
} 

Et voici mon code C++:

#include <iostream> 
    #include <windows.h> 
    #include <jni.h> 
    #include "PTAPIWrapperForOmegaT.h" 

    using namespace std; 

    JNIEXPORT jstring JNICALL Java_PTAPIWrapperForOmegaT_translateWithPTAPI(JNIEnv *env, jobject obj, jstring sentence) 
    { 
/* stuff */ 
    } 

    JNIEXPORT void JNICALL Java_PTAPIWrapperForOmegaT_test(JNIEnv *, jobject) 
    { 
     cout << "This comes from PTAPIWrapperForOmegaT.cpp test();" << endl; 
    } 


    int main(){ 
     return 0; 
    } 

Et le fichier d'en-tête:

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class PTAPIWrapperForOmegaT */ 

#ifndef _Included_PTAPIWrapperForOmegaT 
#define _Included_PTAPIWrapperForOmegaT 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  PTAPIWrapperForOmegaT 
* Method: translateWithPTAPI 
* Signature: (Ljava/lang/String;)Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_PTAPIWrapperForOmegaT_translateWithPTAPI 
    (JNIEnv *, jobject, jstring); 

/* 
* Class:  PTAPIWrapperForOmegaT 
* Method: test 
* Signature:()V 
*/ 
JNIEXPORT void JNICALL Java_PTAPIWrapperForOmegaT_test 
    (JNIEnv *, jobject); 

#ifdef __cplusplus 
} 
#endif 
#endif 

et comment je le construire:

call g++ -Wl,--add-stdcall-alias -c -DBUILDING_EXAMPLE_DLL -I G:/Software/Java/jdk1.7.0_01/include -I G:/Software/Java/jdk1.7.0_01/include/win32 PTAPIWrapperForOmegaT.cpp 
call g++ -shared -Wl,-kill-at -o PTAPIWrapperForOmegaT.dll -I G:/Software/Java/jdk1.7.0_01/include -I G:/Software/Java/jdk1.7.0_01/include/win32 PTAPIWrapperForOmegaT.cpp 

et enfin, l'erreur:

10211: Error: Uncatched exception in thread [Thread-14] 
10211: Error: java.lang.UnsatisfiedLinkError: org.lingenio.util.PTAPIWrapperForOmegaT.test()V 
10211: Error: at org.lingenio.util.PTAPIWrapperForOmegaT.test(Native Method) 
10211: Error: at org.lingenio.util.PTAPIWrapperForOmegaT.<init>(PTAPIWrapperForOmegaT.java:13) 
10211: Error: at org.omegat.core.machinetranslators.LingenioTranslate.translate(LingenioTranslate.java:32) 
10211: Error: at org.omegat.core.machinetranslators.BaseTranslate.getTranslation(BaseTranslate.java:64) 
10211: Error: at org.omegat.gui.exttrans.MachineTranslateTextArea$FindThread.search(MachineTranslateTextArea.java:122) 
10211: Error: at org.omegat.gui.exttrans.MachineTranslateTextArea$FindThread.search(MachineTranslateTextArea.java:102) 
10211: Error: at org.omegat.gui.common.EntryInfoSearchThread.run(EntryInfoSearchThread.java:85) 

Je ne sais pas exactement sur ces deux lignes de g ++ ici, je pense que le deuxième serait suffisant, mais certains tutoriel doit avoir offert l'autre ligne aussi bien et je l'ai gardé.

Je suis sur Windows 7, en utilisant MingW et le dernier Java (1.7xxx je crois).

Toute aide est appréciée, je soupçonne que l'erreur réside dans la compilation, mais je ne sais pas comment continuer à partir d'ici.

EDIT:

En regardant dans le dll avec DependencyWalker je peux voir les fonctions sont nommées comme je les ai nommés dans le fichier .cpp. Bien sûr, je les appelle du Java Wrapper avec leurs noms respectifs, c'est-à-dire test(). Cela pourrait-il être un problème? Est-ce que quelqu'un qui a déjà utilisé JNI peut souvent me dire si c'est la bonne façon?

+0

cela peut sembler étrange, mais essayez de supprimer .dll le nom du fichier où vous chargez la bibliothèque. Le projet sur lequel je travaille actuellement n'accepte pas .dll à la fin du nom de fichier –

+0

Cela conduit juste à l'UnsatisfiedLinkError passant de (méthode native) à (source inconnue). System.load() est en fait le bon moyen de charger une DLL qui n'est pas sur le chemin d'accès standard System.loadLibrary(). – mknaf

+0

Essayez de déplacer la DLL dans le répertoire source et en utilisant 'loadLibrary()' –

Répondre

4

Il s'avère que tout le code est correct. En fait, je fait faire des erreurs de compilation des fichiers d'en-tête. Vous pouvez voir si vous regardez les fichiers d'en-tête de noms de fonction, à savoir:

JNIEXPORT jstring JNICALL Java_PTAPIWrapperForOmegaT_translateWithPTAPI 
    (JNIEnv *, jobject, jstring); 

Maintenant, jetez un oeil à vos fichiers Java de l'adhésion de paquet, dans mon cas:

package org.lingenio.util; 

Parce que je l'ai fait compiler l'en-tête fichier dans le mauvais sens, JNI a ensuite été incapable de trouver les symboles qu'il cherchait, car il cherchait en fait pour cela:

JNIEXPORT jstring JNICALL Java_org_lingenio_util_PTAPIWrapperForOmegaT_translateWithPTAPI(JNIEnv *env, jobject obj, jstring sentence) 

Alors, bonne chance aux gens ballants là-bas avec le sam e problèmes. Je ne suis évidemment pas le meilleur programmeur Java, c'est pourquoi j'ai dû m'inquiéter à ce sujet pendant si longtemps. J'aurais dû compiler mes fichiers d'en-tête de la bonne façon en premier lieu. Vérifiez votre paquet et classpath!

+0

J'ai ce même problème ... en gros, ma fonction est nommée pour correspondre au paquet X, mais j'essaie d'appeler la méthode du paquet Y. Pourriez-vous expliquer quelle est la façon "correcte" de compiler les en-têtes? – bugfixr

+0

Je pense que j'ai juste foiré avec les noms des fonctions. Comme vous pouvez le voir, le paquet est appelé org.lingenio.util, et donc les en-têtes compilés devraient également contenir cette information - vous pouvez le voir dans le troisième panneau de code de la réponse: "Java_org_lingenio_util_yadda". J'ai fait l'erreur de chercher "yadda" au lieu de "Java_org_lingenio_util_yadda". – mknaf

Questions connexes