回调作为C结构的参数
当自由函数作为参数传递给另一个函数时,我对简单回调没有问题,这要感谢@flexo。
但是假设C接口比较困难:
typedef struct
{
int id;
const char* name;
} Item;
typedef struct
{
int value;
Items_Callback callback;
void *context;
} Items_Call;
typedef int (*Items_Callback)(const Item *item, void *context);
int Items_create(const Item *item, Items_Call *call) {
...
call->callback(item, call->context);
...
}
我打算为这样的代码生成一些漂亮的Java包装器。 我假设结果如此
class Item {
public int id;
public String name;
}
class Items_Call {
public int value;
public Object context;
public Interface callback;
public void setInterface(Interface i){ callback=i; };
}
public interface Interface {
public int Items_Callback(Item item, Object context);
}
int Items_create(Item item, Items_Call call) {
...
call.callback.Items_Callback(item, call.context);
...
}
我意识到SWIG在生成纯Java接口时存在一些问题,但我相信这不是主要问题。 问题是我不知道如何将这种嵌套结构重新解释为可接受的Java代码。
不是SWIG,但下面的工作与JavaCPP(它没有伴随着JNA的开销,并且在JNI工作的任何地方工作):
// items.h
typedef struct
{
int id;
const char* name;
} Item;
typedef int (*Items_Callback)(const Item *item, void *context);
typedef struct
{
int value;
Items_Callback callback;
void *context;
} Items_Call;
int Items_create(const Item *item, Items_Call *call) {
// ...
call->callback(item, call->context);
// ...
return 0;
}
在Java中:
import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;
@Platform(include="items.h")
public class Items {
static { Loader.load(); }
public static class Item extends Pointer {
public Item() { allocate(); }
private native void allocate();
public native int id(); public native Item id(int id);
@Cast("const char*")
public native BytePointer name(); public native Item name(BytePointer name);
}
public static class Items_Callback extends FunctionPointer {
protected Items_Callback() { allocate(); }
private native void allocate();
public native int call(@Const Item item, Pointer context);
}
public static class Items_Call extends Pointer {
public Items_Call() { allocate(); }
private native void allocate();
public native int value(); public native Items_Call value(int value);
public native Pointer context(); public native Items_Call context(Pointer context);
public native Items_Callback callback(); public native Items_Call callback(Items_Callback value);
public void setInterface(Items_Callback i) { callback(i); }
}
public static native void Items_create(Item item, Items_Call call);
public static void main(String[] args) {
BytePointer s = new BytePointer("Hello");
Item i = new Item();
i.id(42);
i.name(s);
Items_Callback cb = new Items_Callback() {
public int call(Item item, Pointer context) {
System.out.println(item.id() + " " + item.name().getString());
return 0;
}
};
Items_Call ic = new Items_Call();
ic.callback(cb);
Items_create(i, ic);
// if we remove these references, the GC may prematurely deallocate them
s.deallocate();
cb.deallocate();
}
}
哪一个输出预期的结果:
42 Hello
免责声明:我是JavaCPP的作者:)
链接地址: http://www.djcxy.com/p/76463.html上一篇: Callback as parameter of C structure
下一篇: Why do download via SDM from dream spark stops periodically?