I'm trying to use JNA with a DLL in Windows, so far I was able to successfully call a function called c_aa_find_devices()
. But all the functions start with c_aa
and I would like to rename it to find_devices()
.
From what I gather the way to do this is with StdCallFunctionMapper
but I can't find the documentation of how to use it in an example (i.e. how to map a DLL function by name or by ordinal to a desired name in the wrapped Java library interface). Any suggestions on where the docs are?
A complete working example, using a function 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", "testMethod@0");
}
};
@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 testMethod@0
}
}
Using StdCallMapper won't do good - it is supposed to map werid windows std lib names that have embedded total byte lenght of parameters embedded as part of the name. Since it is done to std lib only (just guessing on that, but 99% you'r functions are not the case).
If your dll uses some common prefix on all functions you need just to use something like:
class Mapper implements FunctionMapper{
public String getFunctionName(NativeLibrary library, Method method) {
return GenieConnector.FUNCTION_PREFIX + method.getName();
}
}
Where GenieConnector.FUNCTION_PREFIX
is that common prefix. Bear in mind that i implement FunctionMapper
, not extend StdCallMapper
From the documentation you need to provide a FunctionMapper in the original call to loadLibrary that converts the name. However you also need to keep the standard call mapping so try something like the following:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With