我想从java中的c ++ dll中读取一些函数。
这是c ++中dll代码的一部分:
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);
这是在java中读取dll的代码:
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() );
}
}
它返回给我这个错误:
Exception in thread "main" java.lang.IllegalArgumentException: Unsupported argument type com.company.Callback at parameter 2 of function S11
我做错了什么?
在Get_P1方法中,一个值被赋值给参数P1,当返回时我希望它保持该值,类似于C#中的参数。调用此方法的正确方法是什么?
答案 0 :(得分:1)
您的InterestingEvent
界面需要扩展JNA的Callback
界面(因此请将您的Callback
类重命名为其他内容)。有关详细信息,请参阅Callbacks, Function Pointers and Closures。
至于Get_P1()
的第二个参数,请使用PointerByReference
代替String[]
。有关详细信息,请参阅Using ByReference Arguments。在这种情况下,您可以使用PointerByReference.getValue()
获取表示返回的char*
值的Pointer
,然后使用Pointer.getString()
将其转换为String
。
试试这个:
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);
}
}