Я хочу использовать epanet.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");
}
}
Затем Джава создал de .hfile
/* 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
Затем я создал файл .c, который должен вызывать epanet2 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 = 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.
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 *);
Я не знаю, как получить long * в mydll, потому что строка -> jstring или int -> jint, но long* ->?или int * ->?