usar desde consumir java dll jna

java - desde - renombrar funciones DLL en JNA usando StdCallFunctionMapper



usar dll c# en java (4)

De la documentación necesita proporcionar un FunctionMapper en la llamada original a loadLibrary que convierte el nombre. Sin embargo, también debe mantener el mapeo de llamadas estándar, intente algo como lo siguiente:

Map options = new HashMap(); options. put( Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionWrapper() { public String getFunctionName(NativeLibrary library, Method method) { if (method.getName().equals("findDevices") method.setName("c_aa_find_devices"); // do any others return super.getFunctionName(library, method); } } ); Native.loadLibrary(..., ..., options);

c_aa_find_devices() utilizar JNA con una DLL en Windows, hasta ahora pude llamar con éxito una función llamada c_aa_find_devices() . Pero todas las funciones comienzan con c_aa y me gustaría cambiarle el nombre a find_devices() .

De lo que encuentro la forma de hacerlo es con StdCallFunctionMapper pero no puedo encontrar la documentación de cómo usarlo en un ejemplo (es decir, cómo asignar una función DLL por nombre o por ordinal a un nombre deseado en la biblioteca envuelta de Java) interfaz). ¿Alguna sugerencia sobre dónde están los documentos?


El uso de StdCallMapper no servirá para nada; se supone que debe asignar nombres de biblioteca estándar de windows werid que tengan incrustados bytes totales de parámetros incrustados como parte del nombre. Ya que está hecho para std lib solamente (solo para adivinar eso, pero el 99% de sus funciones no son el caso).

Si su dll usa algún prefijo común en todas las funciones, solo necesita usar algo como:

class Mapper implements FunctionMapper{ public String getFunctionName(NativeLibrary library, Method method) { return GenieConnector.FUNCTION_PREFIX + method.getName(); } }

Donde GenieConnector.FUNCTION_PREFIX es ese prefijo común. Tenga en cuenta que implemento FunctionMapper , no extiendo StdCallMapper


Toda la documentación de JNA se encuentra en la página web principal , la descripción general de JavaDoc y los propios JavaDocs .

El ejemplo anterior es la idea correcta, ya que necesita ajustar el nombre de la función devuelto por el genérico StdCallFunctionMapper (suponiendo que esté utilizando la convención de llamadas stdcall). Sin embargo, Method.setName () no existe y no le gustaría llamar si lo hizo. Deberá obtener el resultado de String y reemplazar el nombre de la función de Java con el nombre nativo de destino, por ejemplo

name = super.getFunctionName(); name = name.replace("find_devices", "c_aa_find_devices");

De forma más genérica, puede simplemente insertar un prefijo "c_aa_" en el nombre devuelto (o después de cualquier guion bajo), ya que las decoraciones de stdcall se encuentran al final del nombre.


Un ejemplo de trabajo completo, utilizando un mapeador de funciones.

import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; import com.sun.jna.win32.StdCallFunctionMapper; import java.io.File; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; public class JnaTest { static { Map options = new HashMap(); options. put( Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper() { HashMap<String, String> map = new HashMap() { { put("testMethod", "testMethod@0"); } }; @Override public String getFunctionName(NativeLibrary library, Method method) { String methodName = method.getName(); return map.get(methodName); } } ); File LIB_FILE = new File("test.dll"); Native.register(NativeLibrary.getInstance(LIB_FILE.getAbsolutePath(), options)); } private static native int testMethod(); public static void main(String[] args) { testMethod(); // call the native method in the loaded dll with the function name testMethod@0 } }