Llamar al método API de Win32 desde Java

Necesito llamar a algunos métodos en Wininet.dll desde un progtwig 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 a javah en javah ? ¿Dónde obtengo una copia de Wininet.h? Un puntero a un tutorial existente y detallado sería suficiente.

  1. JNA parece ser el estándar de la industria de lo que desea, “proporciona a los progtwigs Java fácil acceso a las bibliotecas compartidas nativas (DLL en Windows) sin escribir nada, excepto código Java, no se requiere JNI o código nativo”

  2. También existe la Interfaz de Función Extranjera de Java : uso de ejemplos
    Si está bien para usted, puede insertar el intérprete JRuby y llamar a winapi a través de jruby-ffi, que es mucho más fácil, vea aquí , aquí y aquí

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

Primero haces tu clase. Aquí hay 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 viene en el JDK, que tomará automáticamente su clase y generar archivos .h y .c. El comando es “javah”. La firma del método se verá algo así:

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

En el archivo .c, incluya los encabezados de Windows que necesite y desarrolle 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 que no cambie el nombre del método, así es como se asocia con su clase específica.

Una vez que lo tienes, comstacks esos archivos en una 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, básicamente has terminado. 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 tu código (lo puse en un bloque estático en mi clase) necesitarás esta línea:

 System.loadLibrary("JNIHelper"); 

Esto hará que Java cargue la biblioteca llamada “JNIHelper.dll” y la enlace al código. Tiene que estar en algún lugar de la ruta de la biblioteca que Java conozca.

Eso es. Es un montón de repetitivo, pero si estás haciendo un envoltorio simple, es fácil. Si tiene que tratar con tipos Java o asignar memoria, empeora (nota: no lo hice, entonces no tengo experiencia allí).

Aquí hay un tutorial completo (primero encontré hoy que parecía decente, y puedes encontrar otros en la web. El artículo de Wikipedia sobre JNI también contiene más información).

Espero que esto ayude.

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 archivo de cabecera para wininet.dll, es probable que necesite tener Platform SDK (o Windows SDK, la versión más reciente). También puede buscar en la red un repository en línea que contenga este archivo de encabezado.

GlueGen necesitará un archivo de cabecera, un comstackdor ANSI C, etc.

También hay una biblioteca menos conocida llamada 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 usado esto, todavía, pero parece prometedor:

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