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?
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 –
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
Essayez de déplacer la DLL dans le répertoire source et en utilisant 'loadLibrary()' –