我正在尝试在Windows中使用带有DLL的JNA,到目前为止,我能够成功调用名为c_aa_find_devices()
的函数。但所有功能都以c_aa
开头,我想将其重命名为find_devices()
。
从我收集的方式来看,这是StdCallFunctionMapper
但我找不到如何在一个例子中使用它的文档(即如何通过名称或序数映射到DLL函数包装的Java库接口中的所需名称)。关于文档在哪里的任何建议?
答案 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 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装饰位于名称的末尾。