I am using C# assembly in a Java application via JNA & Unmanaged Exports. Now I would need to implement a Callback/Delegate in order to inform Java that some Event in the C# .dll has occured.
How can this be accomplished? or is there any reading reference you could suggest?
What I tried so far: I am using Java Native Access (JNA) & unmanaged exports by Robert Giesecke in order to call C# methods from Java. - works fine so far.
I pass the Callback-method as a void* pointer from Java to C#. I would like to call this Method somehow.
For verification I added the code I use:
Defining JNA Interface (incl. Callback) in Java:
import com.sun.jna.Callback;
import com.sun.jna.Library;
public interface Ijna extends Library {
interface sig_t extends Callback {
boolean invoke(int signal);
}
String TestCallback(sig_t callbackparam);
}
unsafe C# Method exported to unmanaged code, receiving a "any pointer" (void*) as parameter which should be the adress of the method
[DllExport]
public unsafe static String TestCallback(void* someMethod) {
//use someMethod here
if(someMethod != null)
return "not null"; // someMethod is not null when running the app
else
return "null";
}
Load .dll, define Callback function and call it in Java.
public static void main(String[] args) {
//load unmanaged .dll
Ijna.sig_t referenceToFunction = new Ijna.sig_t() {
@Override
public boolean invoke(int sig) {
System.out.println("signal " + sig + " was raised");
return true;
}
};
String test = INSTANCE.TestCallback(referenceToFunction);//returns "not null"
System.out.println(test);
}
I could solve it. Using Marshal.GetDelegateForFunctionPointer(IntPtr, Type) it was possible to convert the void* (any pointer) to a C# delegate.
So the C# code is adapted to the following:
delegate void Del(int someInt);
Del csharpfuncptr; //save the Delegate, but not the void* (the void* is not preventing the GB from deleting the method, and could therefore get invalid)
[DllExport]
public unsafe static String TestCallback(void* someMethod)
{
IntPtr method = new IntPtr(someMethod);
csharpfuncptr = (Del)Marshal.GetDelegateForFunctionPointer(method, typeof(Del));
csharpfuncptr(5);
}