Функция обратного вызова JNA с дополнительным аргументом - PullRequest
0 голосов
/ 07 сентября 2018

У меня проблемы с получением JNA. Я пытаюсь вызвать функцию, которая принимает в качестве аргументов указатель на функцию и const char*. Мой код C выглядит так:

typedef void (*example_ptr)(const char*);

void exampleMethod(const char* value)
{
    printf("This is the string: %s\n", value);
}

void example_triggerCallback(const example_ptr func, const char* str) {
    printf("provided str: %s", str);
    func(str);
}

Для этого я написал такую ​​оболочку JNA на Java

public class Main {

    public interface TestLibrary extends Library {

        TestLibrary INSTANCE = (TestLibrary)
                Native.loadLibrary("libtest",
                        TestLibrary.class);

        interface ExampleCallback extends Callback {
            void invoke(String str);
        }

        class ExampleCallbackImpl implements ExampleCallback {
            public void invoke(String str) {
                System.out.println("example: " + str);
            }
        }

        void example_triggerCallback(ExampleCallback callback, String str);
    }

    public static void main(String[] args) {

        TestLibrary testLibrary = TestLibrary.INSTANCE;
        final TestLibrary.ExampleCallbackImpl callback = new TestLibrary.ExampleCallbackImpl();
        testLibrary.example_triggerCallback(callback, "testiddy test test");
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что код printf in example_triggerCallback в C на самом деле вызывается, и я получаю вывод на консоль Java, но здесь я действительно пытаюсь добиться того, что я хотел бы передать со стороны Java указатель на exampleMethod из C, чтобы он печатал переданный String. Прямо сейчас func(str), кажется, игнорируется. Что мне здесь не хватает?

1 Ответ

0 голосов
/ 07 сентября 2018

На основании чего-то найденного в документации JNA :

typedef void (*ExampleCallback)(const char*);

void exampleMethod(const char* value)
{
    printf("This is the string: %s\n", value);
}

void example_triggerCallback(const example_ptr func, const char* str) {
    printf("provided str: %s", str);
    func(str);
}
public interface CLibrary extends Library {
    // define an interface that wraps the callback code
    public interface ExampleCallbackInterface extends Callback {
        void invoke(String val);
    }

        // functions available in library (name must match)
    public void exampleMethod(String  value);
    public void example_triggerCallback(ExampleCallbackInterface callback);
}

// define an implementation of the callback interface
public static class CallbackExample implements Example22CallbackInterface {
    private CLibrary lib;

    public CallbackExample(CLibrary useLib) {
        lib = useLib;
    }

    @Override
    public void invoke(String val) {
        lib.exampleMethod(val);
    }
}

...
final CLibrary clib = (CLibrary)Native.loadLibrary("testlib", CLibrary.class);
...
// instantiate a callback wrapper instance
final CallbackExample callback = new CallbackExample(clib);

// pass the callback wrapper to the C library
clib.example_triggerCallback(callback);

Поскольку я ответил на этот вопрос в каком-то другом месте в Интернете, я знаю, что он работает для спрашивающего.

...