Search code examples
javaencodingcharacter-encodingjna

JNA: Change String encoding for only one external native library


We have here an JAVA application which loads and use a lots of external librarys. The default encoding of the operating system (Windows) is "windows-1252" (or "cp-1252"). But there is one external library which want all String (incoming and outgoing) in "utf-8". How can I do that? How can I change the String encoding type for only one JNA library?


Solution

  • The normal JNA pattern is this:

    public interface DemoLibrary extends Library {
    
        DemoLibrary INSTANCE = Native.load("demoLibrary", DemoLibrary.class);
    
        // abstract method declarations as interface to native library
    }
    

    However, Native#load is overloaded multiple times to support customizing the bindings. The relevant overload is: Native#load(String, Class, Map<String,?>). The third argument can be used to pass options to the native library loader. The options can be found in the com.sun.jna.Library Interface.

    The relevant option here is Library.OPTION_STRING_ENCODING. That option is passed to the NativeLibrary instance loaded and will be used as the default encoding for this class.

    The sample above becomes then

    public interface DemoLibrary extends Library {
    
        DemoLibrary INSTANCE = Native.load("demoLibrary", DemoLibrary.class,
            Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8"));
    
    }
    

    If you need to customize more (typemapper, calling convention), you'll need to create the option map for example in a static initializer block.