I want to read some functions from a c++ dll in java.
This is a part of the dll code in c++:
typedef void(*E1)(int P1, char * P2);
__declspec(dllimport) void S11(int id, char* P1, E1 callback);
__declspec(dllimport) void Get_P1(int id, char** P1);
And this is the code to read the dll in java:
interface InterestingEvent
{
public void interestingEvent(int id, String P1);
}
class Callback implements InterestingEvent {
@Override
public void interestingEvent(int id, String P1) {
System.out.print("The the event "+ id + " throw this error: " + P1 + "\n");
}
}
public class Main{
public interface Kernel32 extends Library {
public void S11(int id, String P1, InterestingEvent callback);
public void Get_P1(int id, String[] P1);
}
public static void main(String[] args) {
Kernel32 lib = (Kernel32) Native.loadLibrary("path\\to\\dll",
Kernel32.class);
lib.S11(id, "some string", new Callback() );
}
}
And it returns me this error:
Exception in thread "main" java.lang.IllegalArgumentException: Unsupported argument type com.company.Callback at parameter 2 of function S11
what am I doing wrong?
And in the Get_P1 method a value is assigned to the parameter P1 and when return I want it to keep that value, similar to the parameters out in C#. What would be the correct way to invoke this method?
Your InterestingEvent
interface needs to extend JNA's Callback
interface (so rename your Callback
class to something else). See Callbacks, Function Pointers and Closures for more details.
As for the 2nd parameter of Get_P1()
, use PointerByReference
instead of String[]
. See Using ByReference Arguments for more details. In this case, you can use PointerByReference.getValue()
to get a Pointer
representing the returned char*
value, and then you can convert that to a String
using Pointer.getString()
.
Try this:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Callback;
import com.sun.jna.ptr.PointerByReference;
interface InterestingEvent extends Callback
{
public void interestingEvent(int id, String P1);
}
class MyCallback implements InterestingEvent {
@Override
public void interestingEvent(int id, String P1) {
System.out.print("The the event "+ id + " throw this error: " + P1 + "\n");
}
}
public class Main{
public interface Kernel32 extends Library {
public void S11(int id, String P1, InterestingEvent callback);
public void Get_P1(int id, PointerByReference P1);
}
public static void main(String[] args) {
Kernel32 lib = (Kernel32) Native.loadLibrary("path\\to\\dll",
Kernel32.class);
lib.S11(id, "some string", new MyCallback() );
PointerByReference p = new PointerByReference();
lib.Get_P1(id, p);
String str = p.getValue().getString(0);
}
}