Java:加载带有char **的C DLL,将回调作为参数

Java: load c++ dll with char** and callback as parameters

本文关键字:回调 参数 DLL 加载 Java char      更新时间:2023-10-16

我想从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#中的参数。调用此方法的正确方法是什么?

您的InterestingEvent接口需要将JNA的Callback接口扩展(因此将Callback类重命名为其他内容(。有关更多详细信息,请参见回调,功能指针和关闭。

至于Get_P1()的第二个参数,请使用PointerByReference而不是String[]。有关更多详细信息,请参见使用ByReference参数。在这种情况下,您可以使用PointerByReference.getValue()获取代表返回的char*值的Pointer,然后可以使用Pointer.getString()将其转换为CC_11。

尝试以下操作:

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);
    }
}