Java: 以 char** 和回调作为参数加载 c++ dll

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

我想从 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() );
    }
}

它 return 给我这个错误:

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported argument type com.company.Callback at parameter 2 of function S11

我做错了什么?

并且在 Get_P1 方法中,一个值被分配给参数 P1,当 return 我希望它保留该值,类似于 C# 中的参数输出。调用此方法的正确方法是什么?

您的 InterestingEvent 接口需要扩展 JNA 的 Callback interface (so rename your Callback class to something else). See Callbacks, Function Pointers and Closures 以获得更多详细信息。

至于Get_P1()的第二个参数,使用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().

试试这个:

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