I have got problem getting JNA all worked out. I am trying to invoke a function that takes as a arguments pointer to function and const char*
. My C code looks like this:
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);
}
To get this going I wrote such JNA wrapper in 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");
}
}
The problem I am facing is that the printf
in example_triggerCallback
in C code is in fact being called and I am getting the output on Java console but what I am really trying to achieve here is that I would like to pass from Java side the pointer for the exampleMethod
from C so it would be printing the passed String
. Right now func(str)
seems to be ignored. What am I missing here?
Based on something found in JNA documentation:
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);
Since I answered this question in some other internet location, I know that it works for the questioner.