【问题标题】:Provide different method name in interface在接口中提供不同的方法名称
【发布时间】:2016-03-01 14:35:45
【问题描述】:

我完全不懂Java,但我必须解决这个问题。我正在使用 JNA 并在一个文件中:

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

它就像一个魅力。但取决于平台,由于 Linux .so 和 Windows .dll 之间的导出符号命名不匹配,我必须使用 Rockey 方法而不是 rockey。我尝试使用 perl -pi -e 's/rockey/Rockey/g' lib.so 替换 so 文件中的符号名称,但它不起作用(此后找不到符号 'Rockey',尽管进行了替换)。

所以我的问题是,如何以最简单的方式(不是最漂亮的方式)以编程方式解决这个问题。非常感谢!

【问题讨论】:

  • 在这种情况下,您可能不想尝试控制从库导出的符号的大小写。为什么不检查您正在运行的操作系统并进行适当的调用?见stackoverflow.com/questions/228477/…
  • 您可以尝试使用反射,例如根据您在JRockey4ND.class 中查找方法“rokey”或“Rockey”的操作系统。
  • 谢谢@Thomas,听起来很不错。但是我应该如何修改我的界面以便它能够提供这两种方法呢?我不能直接在界面主体中检查操作系统。
  • 嗯,我可能不会更改接口,而是检查loadLibrary 调用返回的实现类,即使用rockey.getClass() 来获取它。然后使用getMethod("rockey", <parameter types>)获取小写方法。如果它不存在,即你得到一个MethodNotFoundException,那么尝试使用方法名称"Rockey"。但是,问题是我有一段时间没有使用 JNA,所以如果方法名称不合适,我不知道你是否可以加载库。如果是这种情况,那么您最好解决案例问题。
  • Rockey 是第三方库吗?如果是这样,有没有办法重新编译它并在符号生成/导出期间更改名称?如果没有,您可以尝试编写一个适配器,以正确的大小写提供方法名称并将调用委托给实际的库。

标签: java shared-libraries jna


【解决方案1】:

根据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();

} }; 地图选项 = new HashMap(); options.put(库.OPTION_FUNCTION_MAPPER,映射器); Native.loadLibrary("rocket", Rocket.class, options);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 2015-11-21
    • 1970-01-01
    • 2019-06-08
    • 2017-01-19
    相关资源
    最近更新 更多