我想要使用epanet.dll,所以爲了調用它我必須創建我的橋dll。JNI問題:在Java中調用使用第三方DLL的dll
我創建的Java類
public class Epanet {
//Native method declaration
native int ENopen(String fileInput, String fileOutput, String optBinFileOut);
native int ENsaveinpfile(String file);
native int ENclose();
native int ENsolveH();
native int ENsaveH();
native int ENopenH();
//native int ENrunQ(long *);
//Load the library
static {
System.loadLibrary("epanet2");
}
}
然後JAVAH德.h文件中創建
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class Epanet */
#ifndef _Included_Epanet
#define _Included_Epanet
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_Epanet_ENopen (JNIEnv *, jobject, jstring, jstring, jstring);
JNIEXPORT jint JNICALL Java_Epanet_ENsaveinpfile (JNIEnv *, jobject, jstring);
JNIEXPORT jint JNICALL Java_Epanet_ENclose (JNIEnv *, jobject);
JNIEXPORT jint JNICALL Java_Epanet_ENsolveH (JNIEnv *, jobject);
.....
.....
#ifdef __cplusplus
}
#endif
#endif
然後我創建的應該叫epanet2 DLL .c文件
#include "jni.h"
#include <stdio.h>
#include "myDll.h"
#include "epanet2.h"
JNIEXPORT jint JNICALL Java_Epanet_ENopen
(JNIEnv *env, jobject obj, jstring fichIn, jstring fichOut, jstring fichBin){
const char *CStringFichIn = (*env)->GetStringUTFChars(env,fichIn,NULL);
const char *CStringFichOut = (*env)->GetStringUTFChars(env,fichOut,NULL);
const char *CStringFichBin = (*env)->GetStringUTFChars(env,fichBin,NULL);
int result;
result = ENepanet (CStringFichIn, CStringFichOut, CStringFichBin, NULL);
(*env)->ReleaseStringUTFChars(env, fichIn, CStringFichIn);
(*env)->ReleaseStringUTFChars(env, fichOut, CStringFichOut);
(*env)->ReleaseStringUTFChars(env, fichBin, CStringFichBin);
return result;
}
JNIEXPORT jint JNICALL Java_Epanet_ENsaveinpfile
(JNIEnv *env, jobject object, jstring fichOut){
const char *CStringFichOut;
int result;
CStringFichOut = (*env)->GetStringUTFChars(env,fichOut,NULL);
result = ENsaveinpfile (CStringFichOut);
return result;
}
JNIEXPORT jint JNICALL Java_Epanet_ENclose
(JNIEnv *env, jobject object){
int result;
result = ENclose();
return result;
}
JNIEXPORT jint JNICALL Java_Epanet_ENsolveH
(JNIEnv *env, jobject object){
int result;
result = ENsolveH();
return result;
}
JNIEXPORT jint JNICALL Java_Epanet_ENsaveH
(JNIEnv *env, jobject object){
int result;
result = ENsaveH();
return result;
}
JNIEXPORT jint JNICALL Java_Epanet_ENopenH
(JNIEnv *env, jobject obj){
int result;
result = ENopenH();
return result;
}
而且然後編譯。 Visual C++創建我的dll。我在system32中複製了這兩個DLL。然後我嘗試使用我的dll。
public class NewClass {
private native void ENopen(String f1, String f2, String f3);
public static void main(String[] args) {
System.out.println("started");
new NewClass().ENopen("C:\\Red2.inp", "C:\\salaida.txt", "");
System.out.println("finished");
}
static {
System.loadLibrary("myDll");
}
}
我得到這個錯誤:
started
Exception in thread "main" java.lang.UnsatisfiedLinkError: NewClass.epanet(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String)V
at NewClass.epanet(Native Method)
at NewClass.main(NewClass.java:18) Java Result: 1
如果我刪除我得到的錯誤說,它不能找到庫,以便有問題的地方圖書館。我必須說,一個朋友給了我他的DLL,但它不適合我。我犯了同樣的錯誤。
任何猜測? 另一個問題是如何調用這個本地方法// native int ENrunQ(long *); ?
那麼這就是你給我建議(主要爲第二個評論):
我EPANET類加載我的DLL,而不是EPANET DLL(第三方之一)。
public class Epanet {
//Native method declaration
native int ENopen(String fileInput, String fileOutput, String optBinFileOut);
native int ENsaveinpfile(String file);
native int ENclose();
native int ENsolveH();
native int ENsaveH();
native int ENopenH();
//native int ENrunQ(long *);
//Load the library
static {
System.loadLibrary("myDll");
}
}
而我的測試類不應該加載它。實際上,它不應該加載Epanet課程。
public class NewClass {
public static void main(String[] args) {
System.out.println("started");
new Epanet().ENopen("C:\\Red2.inp", "C:\\salida.txt", "");
System.out.println("finished");
}
}
然後我包裝DLL應該是這樣的:
#include "jni.h"
#include <stdio.h>
#include "myDll.h"
#include "epanet2.h"
JNIEXPORT jint JNICALL Java_Epanet_ENopen
(JNIEnv *env, jobject obj, jstring fichIn, jstring fichOut, jstring fichBin){
const char *CStringFichIn = (*env)->GetStringUTFChars(env,fichIn,NULL);
const char *CStringFichOut = (*env)->GetStringUTFChars(env,fichOut,NULL);
const char *CStringFichBin = (*env)->GetStringUTFChars(env,fichBin,NULL);
int result;
result = ENopen (CStringFichIn, CStringFichOut, CStringFichBin);
(*env)->ReleaseStringUTFChars(env, fichIn, CStringFichIn);
(*env)->ReleaseStringUTFChars(env, fichOut, CStringFichOut);
(*env)->ReleaseStringUTFChars(env, fichBin, CStringFichBin);
return result;
}
還是更喜歡這樣的:
#include "jni.h"
#include <stdio.h>
#include <windows.h>
#include "myDll.h"
#include "epanet2.h"
typedef int (* FPTR)(char *, char *, char*);
JNIEXPORT jint JNICALL Java_Epanet_ENopen
(JNIEnv *env, jobject obj, jstring fichIn, jstring fichOut, jstring fichBin){
HMODULE dllHandle = LoadLibrary("epanet2.dll"); // cargar librería
const char *CStringFichIn = (char *)(*env)->GetStringUTFChars(env,fichIn,NULL);
const char *CStringFichOut = (char *) (*env)->GetStringUTFChars(env,fichOut,NULL);
const char *CStringFichBin = (char *)(*env)->GetStringUTFChars(env,fichBin,NULL);
int result;
FPTR ENopen = (FPTR) GetProcAddress(dllHandle, "ENopen");
result = ENopen (CStringFichIn, CStringFichOut, CStringFichBin);
(*env)->ReleaseStringUTFChars(env, fichIn, CStringFichIn);
(*env)->ReleaseStringUTFChars(env, fichOut, CStringFichOut);
(*env)->ReleaseStringUTFChars(env, fichBin, CStringFichBin);
FreeLibrary(dllHandle); // descargar librería
return result;
}
而且,你知道如何調用這個函數?
native int ENrunQ(long *);
我不知道怎麼弄長*在MYDLL因爲字符串 - >的jstring或者int - > jint但長* - >?或者int * - >?
你有檢查,你沒有錯誤的DLL躺在你的bin文件夾? – dacwe 2010-11-21 12:33:44
爲什麼你有兩個'loadLibrary(..)'調用?你只有一個界面! – dacwe 2010-11-21 12:37:43
我不知道如何檢查是否有錯誤的DLL。一切正常。 – Alberto 2010-11-21 16:59:31