我正在为移动广告SDK创建一个OpenFL扩展程序,但是我很难弄清一些CFFI内容。
基本上,我试图将Haxe对象传递给C ++,然后从C ++对该对象调用一个方法。这样做的目的是作为事件侦听器,因此当C ++中发生某些事情时,我将在该对象上调用回调以通知Haxe代码。
我知道如何使用Android的lime的JNI东西使用Java来做到这一点。使用JNI type signatures看起来像这样:
var setCallbackListener = JNI.createStaticMethod("com.test.myextension", "setCallbackListener", "(Lorg/haxe/lime/HaxeObject;)V");
var listener = new MyCallbackListener(); //implements `onSomething`
setCallbackListener(listener); //pass the listener to the Java side
然后从Java方面,我可以这样调用函数onSomething
:
public static void setCallbackListener(HaxeObject listener){
listener.call0("onSomething"); //call a function called "onSomething" with zero arguments
}
那行得通,这就是我在Android上的做法。对于iOS,我正在尝试使用hxcpp做同样的事情。
我知道使用cpp.Lib.load
以类似于上面的JNI api的方式从Haxe调用C ++函数的一般过程。但是,一旦我在C ++端获得了value
类型,就不知道如何调用它的成员函数。
例如,假设我的C ++函数看起来像这样:
#include <hx/CFFI.h>
static void setCallbackListener (value listener) {
//...
}
DEFINE_PRIM (setCallbackListener, 1);
然后如何在listener
中调用函数“ onSomething”?
答案 0 :(得分:2)
经过一番挖掘,我发现了!不幸的是,所有这些似乎都没有记录在案,因此我想在这里发表我的发现,以防其他人想做同样的事情。
hxcpp C API显然与Neko十分相似,尽管并不完全相同。不过,Neko documentation是一个很好的起点。
该页面显示了如何使用val_call0
,val_call1
等调用函数。它没有显示出如何从实例获取对所需函数的引用。为此,您可以像这样同时使用函数val_id
和val_field
(这是用于hxcpp,不确定是否也适用于Neko):
#include <hx/CFFI.h>
#include <hx/CFFIAPI.h>
static void setCallbackListener (value listener) {
//get the field "id" from the name, which seems like a generic hash
field fid = val_id("onSomething");
//get the function from `listener`
value myfunc = val_field(
listener, //class instance allocated in haxe (type `value`)
fid
);
//optionally verify that `myfunc` is 1) a function and 2) accepts 0 arguments
//throws haxe error if this check fails
val_check_function(myfunc, 0);
//perform the call to `listener.onSomething()`
val_call0(myfunc);
}
DEFINE_PRIM (setCallbackListener, 1);
如果函数使用2个参数而不是一个参数(例如),那么您将使用val_call2
,并按如下方式调用它:
value arg1 = alloc_string("foo");
value arg2 = alloc_bool(true);
val_call2(myfunc, arg1, arg2); //arguments are of type `value`
还有val_callN
接受任意数量的参数。参见declaration here。
参考:https://github.com/HaxeFoundation/hxcpp/blob/master/project/libs/std/Socket.cpp#L1039
幸运的是,当我用Google搜索“ hxcpp val_call”(不带引号)和one of those links detailed this method.
时,只有3个结果只需通读该线程即可获得完整说明。如果您需要更好的内存管理,则该方法可能是首选,因为它还显示了如何从C ++绑定到hxcpp GC。
我在val_id
和val_field
上找不到任何实际的文档,因此这些方法可能不打算在外部使用,并且可能会在hxcpp的更高版本中更改。我不知道。 ♂️