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