使用StdCallFunctionMapper在JNA中重命名DLL函数

时间:2009-02-05 21:55:17

标签: java dll jna

我正在尝试在Windows中使用带有DLL的JNA,到目前为止,我能够成功调用名为c_aa_find_devices()的函数。但所有功能都以c_aa开头,我想将其重命名为find_devices()

从我收集的方式来看,这是StdCallFunctionMapper但我找不到如何在一个例子中使用它的文档(即如何通过名称或序数映射到DLL函数包装的Java库接口中的所需名称)。关于文档在哪里的任何建议?

4 个答案:

答案 0 :(得分:4)

使用StdCallMapper不会做得好 - 它应该映射werid windows std lib名称,这些名称嵌入了作为名称一部分嵌入的参数的总字节长度。因为它只对std lib做了(只是猜测,但99%你的功能不是这样)。

如果您的dll在所有功能上使用了一些通用前缀,您只需要使用以下内容:

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

其中GenieConnector.FUNCTION_PREFIX是该公共前缀。请记住,我实施FunctionMapper,而不是StdCallMapper

答案 1 :(得分:2)

从文档中,您需要在对loadLibrary的原始调用中提供FunctionMapper,以转换名称。但是,您还需要保留标准调用映射,请尝试以下操作:

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

答案 2 :(得分:2)

一个完整的工作示例,使用函数映射器。

np.save

答案 3 :(得分:1)

所有JNA文档都位于primary web pageJavaDoc overviewJavaDocs本身。

上面的示例是正确的想法,因为您需要调整通用StdCallFunctionMapper返回的函数名称(假设您正在使用stdcall调用约定)。但是,Method.setName()不存在,如果有,您不想调用它。您需要获取String结果并将其中的Java函数名称替换为目标本机名称,例如

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

更一般地说,您可以简单地将“c_aa_”前缀添加到返回的名称(或任何前导下划线之后),因为stdcall装饰位于名称的末尾。