2010-03-05 26 views
32

Necesito llamar al some methods in Wininet.dll desde un programa Java.Llamando al método Win32 API desde Java

Puedo encontrar muchos tutoriales sobre cómo llamar a una nueva DLL que creo desde Java, pero parece que no puedo encontrar ningún tutorial sobre cómo llamar a una DLL ya existente de Java.

Sé que esto involucra a JNI, pero ¿cómo exactamente hago esto? ¿Debo llamar al javah en Wininet.h? ¿Dónde obtengo una copia de Wininet.h? Un puntero a un tutorial existente detallado sería suficiente.

Respuesta

38
  1. JNA parece the industry standard de lo que quiere ", proporciona programas Java fácil acceso a bibliotecas compartidas nativas (DLL) en Windows sin se requiere escribir cualquier cosa menos código Java-ningún código JNI o nativo"

  2. Existe también Java Foreign Function Interface - example usage
    Si bien es fo r usted, usted podría embed el intérprete JRuby y llamar a través de winapi jruby-ffi cual es mucho más fácil, ver here, here y here

+2

Este necesidades un bache - JNA es mucho mejor que el JNI puro para el acceso a la biblioteca nativa. –

+0

+1: JNA es una buena opción. Aunque, debes descubrir cómo mapear la firma de la función en Java. Recientemente utilicé JNA para comunicarme con un bluetooth dispositivo a través de la API Win32 nativa – wierob

+0

JNA es realmente astuto. Cuando se lo estaba explicando a un amigo en el trabajo la otra semana, de hecho fui tan lejos como para decirle que es "mágico". – rob

3

No se puede llamar directamente a las bibliotecas nativas: esto se debe a que Java Native Interface no admite algunos argumentos en los métodos.

Hay algo llamado GlueGen, esto creará un binario separado que enlazará dinámicamente con su DLL nativa. El binario generado es compatible con el JNI y, por lo tanto, puede invocarse desde Java.

http://en.wikipedia.org/wiki/Gluegen

Para obtener un encabezado de archivo para wininet.dll, es probable que necesita tener el SDK de la plataforma (o Windows SDK, la más nueva versión). También puede buscar en la red un repositorio en línea que contenga este archivo de encabezado.

GlueGen tendrá un encabezado de archivo, un compilador de C ANSI, etc.

También hay una biblioteca menos conocido llamado NativeCall, que no requiere GlueGen. Ya tiene binarios que son compatibles con Java. Obviamente, esto es más lento, ya que cargará la DLL dinámicamente a petición de Java. No he utilizado esto, sin embargo, pero suena prometedor:

http://johannburkard.de/software/nativecall/

12

que tenía que hacer esto hace un rato. Necesitarás un compilador de C y los archivos de encabezado de Windows. Usé mingw porque es gratis y solo estaba compilando un pequeño archivo.

Primero haga su clase. Aquí está un ejemplo:

package org.whatever.thingy; 

public class MyClass { 
    // Here is a JNI method, identified by 'native' 

    public static native callWin32Thingy(int x, int y, boolean z); 

    /* At this point, normal class stuff, other methods, variables, whatever */ 
} 

A continuación, utiliza uno de los comandos que se presenta en el JDK, que tendrá automáticamente su clase y generar .hy archivos .c. El comando es "javah". La firma del método se verá algo como esto:

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy 
    (JNIEnv *, jclass, jint, jint, jboolean); 

En el archivo .c, que incluyen todo lo que necesita ventanas cabeceras, y profundizar en el método.

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy 
    (JNIEnv *a, jclass b, jint c, jint d, jboolean e) { 
    // Prep steps.... 

    Win32MethodCallWeCareAbout(x, y, z, hWhatever); 

    // Cleanup stuff... 
} 

Es muy importante no se cambia el nombre del método, eso es lo que se asocia con su clase específica.

Una vez que tenga que compila los archivos en un archivo DLL. Aquí están los comandos que usé para mingw, tendrás que ajustar clases/rutas/etc.

c:/MinGW/bin/gcc -c -Ic:/MinGW/include -I"c:/Program Files/Java/jdk1.5.0_12/include" 
    -I"c:/Program Files/Java/jdk1.5.0_12/include/win32" -D__int64="long long" 
    com_whatever_thingy_MyClass_JNIHelper.c 

c:/MinGW/bin/gcc -shared -o JNIHelper.dll 
    com_whatever_thingy_MyClass_JNIHelper_JNIHelper.o 
    -Wl,--add-stdcall-alias,--kill-at,--output-def,def_file 

Esto producirá algunos archivos, incluido JNIHelper.dll, que es lo que llamé mi DLL.

En este punto, que está básicamente hecho. Usas tu clase Java como siempre, y ejecutará tu código Win32 cuando invoques el método estático. Todo lo que tienes que hacer es importar la biblioteca. En algún lugar de su código (lo pongo en un bloque estático en mi clase) que necesita esta línea:

System.loadLibrary("JNIHelper"); 

Esto hará que Java para cargar la biblioteca llamada "JNIHelper.dll" y vincularlo en el código . Tiene que estar en algún lugar de la ruta de la biblioteca que Java conozca.

Eso es todo. Es un montón de repetitivo, pero si estás haciendo un envoltorio simple, es fácil. Si usted tiene que tratar con los tipos de Java o la asignación de memoria, se pone peor (nota: no lo hice, así que no tienen experiencia allí).

Hay todo un tutorial here (primero me encontré hoy que parecía decente, y se puede encontrar a otras personas en la web. El artículo Wikipedia en JNI tiene más información también.

Espero que esto ayude.

+1

¿Usted no necesita una palabra clave "nativo" en su clase Java? –

+0

@ Thorbjørn: Su derecho, echaba de menos que, gracias. Editado para agregar. – MBCook