Search code examples
javacallbackjna

Is is possible to specify a JNA callback programmatically?


I know how to specify a JNA callback (C to Java) the regular way, like for example:

C header:

static void (*InvokerInst)(int, int);
__declspec(dllexport) int start();
__declspec(dllexport) void setInvoker(void (*InvokerInst)(int, int));

C source:

#include <stdio.h>
#include "main.h"
int start()
{
  InvokerInst(10, 10);
  return 0;
}
void setInvoker(void (*Invoker)(int, int)) {
   InvokerInst = Invoker;
}

Java library interface:

public interface MyLibrary extends Library {
  int start();
  public void setInvoker(Invoker callback);
  public interface Invoker extends Callback {
     void invoke(int val1, int val2);
  }   
}

Java code:

public class JNATest implements Invoker {
   private MyLibrary lib = null;

   public JNATest() {
      String path = System.getProperty("user.dir");
      NativeLibrary.addSearchPath("MyCLib", path);
      lib = (MyLibrary2)Native.load("MyCLib", MyLibrary.class);
      lib.setInvoker(this);
   }
   public void callStart() {
     String result = lib.start("TOTO");
     System.out.println("Result is: " + result);
  }     
  public static final void main(String[] args) {
     JNATest test = new JNATest();
     test.callStart();
  }
  public void invoke(int val1, int val2) {
     System.out.println("Value Invoked: " + (val1 + val2));
  }
}

This works, but is it possible to perform the same thing without defining a Java interface like what is already possible with JNA when calling C DLLs.

For example, I can perform (for Java to C) (supposing that we have a MyCLib.dll library in the user.dir directory):

  String path = System.getProperty("user.dir");
  NativeLibrary.addSearchPath("MyCLib", path);
  lib = NativeLibrary.getInstance("MyCLib"); 

  Function function = lib.getFunction("start");
  Object[] array = new Object[3];
  array[0] = 1f;
  array[1] = 1f;
  array[2] = 10f;
  Object result = function.invoke(Float.class, array);
  System.out.println(result);

with the following C code:

float start(float width, float height, float offset)
{
  printf("start\n");
  return width + height + offset;
}

Solution

  • It seems that it's no possible for the moment in the JNA library