从Haxe传递给C ++的对象中的调用方法

时间:2019-05-18 01:03:26

标签: haxe openfl hxcpp

我正在为移动广告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”?

1 个答案:

答案 0 :(得分:2)

经过一番挖掘,我发现了!不幸的是,所有这些似乎都没有记录在案,因此我想在这里发表我的发现,以防其他人想做同样的事情。

方法1

hxcpp C API显然与Neko十分相似,尽管并不完全相同。不过,Neko documentation是一个很好的起点。

该页面显示了如何使用val_call0val_call1等调用函数。它没有显示出如何从实例获取对所需函数的引用。为此,您可以像这样同时使用函数val_idval_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

方法2

幸运的是,当我用Google搜索“ hxcpp val_call”(不带引号)和one of those links detailed this method.

时,只有3个结果

只需通读该线程即可获得完整说明。如果您需要更好的内存管理,则该方法可能是首选,因为它还显示了如何从C ++绑定到hxcpp GC。

免责声明

我在val_idval_field上找不到任何实际的文档,因此这些方法可能不打算在外部使用,并且可能会在hxcpp的更高版本中更改。我不知道。 ‍♂️