Search code examples
javashared-librariesjna

Provide different method name in interface


I'm complete Java ignorant, yet I've to resolve this problem. I'm using JNA and have in one file:

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

and in another file:

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

and it works like a charm. But depending on platform, I have to use Rockey method instead of rockey due to exported symbols naming mismatch between Linux .so and Windows .dll. I've tried to replace symbol name in so file by using: perl -pi -e 's/rockey/Rockey/g' lib.so but it doesn't work ( symbol 'Rockey' can't be found after that, despite of replacement ).

So my question is, how this can be resolved programmatically in easiest possible way ( not the prettiest one ). Many thanks!


Solution

  • According to the JNA JavaDoc, you can provide a FunctionMapper as an option when initializing your library which maps the method name to the library name.

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

    } }; Map options = new HashMap(); options.put(Library.OPTION_FUNCTION_MAPPER, mapper); Native.loadLibrary("rocket", Rocket.class, options);