Search code examples
javac++jna

Mapping const char** to Java type with JNA


I am trying to use a C++ library in Java with JNA. In the header file of the library I have the following method declaration:

extern "C" void foo(const char** bar);

The paramterer bar should be passed to foo empty, and foo vill assign it a value that I want to retreive in Java. How should the corresponding Java method declaration be set up (e.g. what Java type should I map bar to), and how can I use it?

I have tried the following Java declarations:

void foo(String bar);
void foo(String[] bar);
void foo(Pointer bar);

They all result in the following error when I call foo:

Exception in thread "main" java.lang.Error: Invalid memory access


Solution

  • Find below a small snippet.

    libfoo.cpp

    #include <stdio.h>
    extern "C" void foo(const char** bar);
    
    void foo(const char** bar) {
        for (int i = 0; bar[i] != '\0'; i++) {
            fprintf(stdout, "%s\n", bar[i]);
        }
    }
    

    LibFooDemo.java

    import com.sun.jna.Library;
    import com.sun.jna.Native;
    
    public class LibFooDemo {
    
        public interface FooLibrary extends Library {
            FooLibrary INSTANCE = (FooLibrary)
                    Native.loadLibrary("foo", FooLibrary.class);
            void foo(String[] format);
        }
    
        public static void main(String[] args) {
            String[] vals = {"foo", "bar", "foobar"};
            FooLibrary.INSTANCE.foo(vals);
        }
    }
    

    compile all sources

    gcc -c -fPIC libfoo.cpp -o libfoo.o
    gcc -shared -o libfoo.so  libfoo.o
    javac -cp jna-4.2.1.jar LibFooDemo.java
    

    run the Java program

    java -Djava.library.path=. -cp jna-4.2.1.jar:. LibFooDemo
    

    output

    foo
    bar
    foobar