2016-03-01 2 views
0

Я полностью не осведомлен о Java, но я должен решить эту проблему. Я использую ЮНА и есть в одном файле:Предоставить другое имя метода в интерфейсе

public interface JRockey4ND extends Library { 

    public short rockey(short func, short[] handle, int[] lp1, int[] lp2, short[] p1, short[] p2, short[] p3, short[] p4, byte[] buffer); 
    public short RY_FIND=1; 
    public short RY_FIND_NEXT=2; 
} 

и в другом файле:

JRockey4ND rockey = (JRockey4ND) Native.loadLibrary(libFileName, JRockey4ND.class); 
. 
. 
retval=rockey.rockey(rockey.RY_FIND,handle[0],lp1,lp2,p1,p2,p3,p4,buffer); 

и он работает как шарм. Но в зависимости от платформы я должен использовать метод Rockey вместо rockey из-за несогласованности экспортированных символов между Linux .so и Windows .dll. Я попытался заменить имя символа в таком файле, используя: perl -pi -e 's/rockey/Rockey/g' lib.so, но он не работает (символ «Rockey» не может быть найден после этого, несмотря на замену).

Итак, мой вопрос в том, как это можно решить программно самым простым способом (не самым красивым). Большое спасибо!

+0

В этом случае вы, вероятно, не хотите пытаться контролировать капитализацию символов, экспортируемых из библиотек. Почему бы не выполнить проверку, для какой ОС вы работаете, и сделать соответствующий вызов? См. Http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java –

+1

Вы можете попробовать и использовать отражение, например. в зависимости от ОС вы ищете метод «rockey» или «Rockey» в «JRockey4ND.class». – Thomas

+0

Спасибо @Thomas, звучит очень хорошо. Но как мне изменить свой интерфейс, чтобы он мог обеспечить оба метода? Я не могу просто проверить ОС непосредственно в теле интерфейса. – pikkewyn

ответ

2

В соответствии с JNA JavaDoc вы можете указать FunctionMapper в качестве опции при инициализации библиотеки, которая отображает имя метода в имя библиотеки.

FunctionMapper mapper = new FunctionMapper() { 
    public String getFunctionName(NativeLibrary library, Method method) { 
    if (Platform.isWindows()) { 
     if (method.getName().equals("rocket")) { 
      return "Rocket"; 
     } 
    } 
    return method.getName(); 

} }; Параметры карты = новый HashMap(); options.put (Library.OPTION_FUNCTION_MAPPER, mapper); Native.loadLibrary («ракета», Rocket.class, опции);