2009-02-05 5 views
3

Я пытаюсь использовать JNA с DLL в Windows, до сих пор мне удалось успешно вызвать функцию с именем c_aa_find_devices(). Но все функции начинаются с c_aa, и я хотел бы переименовать его в find_devices().переименование функций DLL в JNA с использованием StdCallFunctionMapper

Из того, что я собираюсь сделать, это StdCallFunctionMapper, но я не могу найти документацию о том, как его использовать в примере (например, как сопоставить функцию DLL по имени или по порядковому номеру с желаемым именем в обернутый интерфейс библиотеки Java). Любые предложения о том, где находятся документы?

ответ

1

Из документации вам необходимо предоставить FunctionMapper в исходном вызове loadLibrary, который преобразует имя. Однако вы также должны иметь стандартное отображение вызова так попробовать что-то вроде следующего:

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); 
+0

Это не проверено. Должен быть 'StdCallFunctionMapper' не' StdCallFunctionWrapper'. И нет такой вещи, как 'method.setName()'. –

1

Вся документация ЮНА находится в primary web page, тем JavaDoc overview, а сами JavaDocs.

Приведенный выше пример правильной идеи заключается в том, что вам нужно настроить имя функции, возвращаемое общим StdCallFunctionMapper (при условии, что вы используете соглашение о вызове stdcall). Однако Method.setName() не существует, и вы не захотите его вызывать, если это произойдет. Вам нужно будет получить результат String и заменить имя функции Java внутри него целевым родным именем, например.

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

Более обобщенно, вы можете просто лавировать на приставку «c_aa_» возвращенное имя (или после любого знака подчеркивания), так как STDCALL украшения в конце имени.

+1

три опубликованных канала связи, FYI ... – Cashew

4

Использование StdCallMapper не принесет пользы - предполагается, что они будут отображать werid windows std имена lib, у которых есть встроенная общая длина байтов параметров, встроенных как часть имени. Поскольку это делается только для std lib (просто догадываясь об этом, но 99% функций you'r не так).

Если длл использует некоторый общий префикс всех функций, которые нужно просто использовать что-то вроде:

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

Где GenieConnector.FUNCTION_PREFIX является то, что общий префикс. Имейте в виду, что я реализую FunctionMapper, не распространяюсь StdCallMapper

1

Полный рабочий пример, используя функцию mapper.

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", "[email protected]"); 
           } 
          }; 
          @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 testMeth[email protected] 
    } 


} 
+0

спасибо, но я боюсь, что не буду оценивать ваш ответ, поскольку это было для задачи, которая мне понадобилась семь лет назад на предыдущей работе. Но если другие люди будут поддерживать вас, это здорово. –

 Смежные вопросы

  • Нет связанных вопросов^_^