2012-02-28 22 views
9

Estoy usando Java para una aplicación pequeña. Es una reescritura de un proyecto MFC existente. Existe una dll existente que necesito cambiar para habilitar el acceso desde Java usando JNI. Todas estas cosas de Java son nuevas para mí, así que estoy teniendo un pequeño problema y me siento bastante denso cuando leo otras publicaciones en el foro. En el dll existente tengo una función como esta:Llamando a C++ dll desde Java

extern "C" __declspec(dllexport) bool Create() 
{ 
    return TRUE; 
} 

Tiempo de pregunta tonto. ¿Cómo configuro correctamente para ser llamado por Java?

yo probamos este:

JNIEXPORT jboolean JNICALL Create() 
{ 
    return TRUE; 
} 

Estoy incluyendo jni.h y todo compila bien. Sin embargo, cuando lo llamo desde Java obtengo UnsatisfiedLinkError. Lo llamo desde Java usando esto:

public static native boolean CreateSession(); 

System.load("D:\\JavaCallTest.dll"); 
Create(); 

¿Alguien podría empujarme amablemente en la dirección correcta? Agradezco sinceramente cualquier ayuda.

Gracias,

Nick

+1

¿Has mirado el ejemplo de Sun? http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html – Etienne

+1

Alternativamente, puede usar JNA en lugar de JNI, ya que tiene un dll C que JNA puede cargar. – ecle

+0

Por favor, publique la excepción que se lanza ... – quaylar

Respuesta

7

es necesario incluir el nombre de la clase de Java y la ruta en el código nativo, por ejemplo, si el método nativo fue declarado en Java como:

public class NativeCode { 
    public static native boolean CreateSession(); 
} 

y la ruta de clase era (por ejemplo) com.example.NativeCode lo haría declarar su método en el nativo de la siguiente manera:

extern "C" 
JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz) 
{ 
    return JNI_TRUE; 
} 

métodos JNI Todos tienen un puntero JNIEnv y clase que sus dos primeros parámetros.

+0

Eso fue todo. Parece estar funcionando ahora. Veremos qué tipo de problemas me encuentro cuando no estoy tratando con una función simple como esta. Aprecio la ayuda. – nickfinity

+0

@GooseSerbus ¿qué pasa con los parámetros utilizados público booleano nativo estático CreateSession (?,?); – Aniket

+0

Los parámetros de @Aniket se agregan a los parámetros en el método C, por ejemplo: 'booleano nativo estático público CreateSession (booleano, Object);' sería 'JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession (JniEnv * env, jclass clazz, jboolean b, jobject o) ' – GooseSerbus

1

yo tuvimos un problema similar - un C-código base existente que necesitaba para acceder desde Java. Para mí, valió la pena, familiarizarse con SWIG, una herramienta para generar una DLL intermedia de C++ (que llama al código C), más el código Java que llama al DLL de C++.

Si usted tiene más de sólo 1 en función de la DLL para envolver, podría pagar a la salida de esta herramienta, de lo contrario tendría que familiarizarse con JNI ...

EDITAR:

Parece que su DLL no se encuentra en la llamada System.load(). Es posible que desee probar System.loadLibrary(), pero tenga en cuenta que su archivo DLL debe estar ubicado en la ruta indicada por la propiedad del sistema de Java java.library.path. Además, no pase el nombre de archivo completo en este caso, solo el nombre de archivo sin extensión.

+0

Encontré la DLL, pero no tenía mi función declarada correctamente. Tendré que buscar en SWIG. Gracias por el consejo. – nickfinity

2

Un método nativo estática todavía necesita al menos dos parámetros:

JNIEnv *env 
jclass clazz 

El nombre de la función también tiene que corresponder la estructura del paquete de java.

JNIEXPORT jboolean JNICALL Java_com_example_CreateSession(JNIEnv *env, jclass clazz) 

Lo ideal sería utilizar la herramienta javah para crear un archivo de cabecera de la clase Java que se declara el método nativo y luego poner en práctica los prototipos de las funciones declaradas.

+0

+1 por mencionar que se debe usar javah para generar las firmas de funciones. –

+0

Encontré esto (http://stackoverflow.com/a/3452258/978528) y configuré Eclipse para ejecutar javah. Trabajando bien ahora. Ahora tengo que implementar el resto de las cosas. Espero que sea sencillo. – nickfinity