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

Ale*_*llo 4 haxe hxcpp openfl

我正在为移动广告SDK创建一个OpenFL扩展程序,但很难弄清一些CFFI内容。

基本上,我试图将Haxe对象传递给C ++,然后从C ++对该对象调用一个方法。这样做的目的是作为事件侦听器,因此当C ++中发生某些事情时,我将在该对象上调用回调以通知Haxe代码。

我知道如何使用lime的用于Android的JNI东西使用Java来做到这一点。使用JNI类型签名看起来像这样:

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

Run Code Online (Sandbox Code Playgroud)

然后,从Java方面,我可以这样调用函数onSomething

public static void setCallbackListener(HaxeObject listener){
    listener.call0("onSomething"); //call a function called "onSomething" with zero arguments
}
Run Code Online (Sandbox Code Playgroud)

那行得通,这就是我在Android上的做法。对于iOS,我尝试使用hxcpp做相同的事情。

我知道从Haxe调用C ++函数的一般过程,其使用cpp.Lib.load方式与上述JNI api类似。但是,一旦获得valueC ++方面的类型,我就不知道如何调用它的成员函数。

例如,假设我的C ++函数如下所示:

#include <hx/CFFI.h>
static void setCallbackListener (value listener) {
    //...
}
DEFINE_PRIM (setCallbackListener, 1);
Run Code Online (Sandbox Code Playgroud)

然后,我将如何在其中调用函数“ onSomething” listener

Ale*_*llo 5

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

方法1

hxcpp C API显然与Neko十分相似,尽管并不完全相同。尽管如此,Neko文档还是一个不错的起点。

该页面显示了如何使用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);
Run Code Online (Sandbox Code Playgroud)

如果该函数使用2个参数而不是一个参数(例如),那么您将使用val_call2,并像这样调用它:

value arg1 = alloc_string("foo");
value arg2 = alloc_bool(true);
val_call2(myfunc, arg1, arg2); //arguments are of type `value`
Run Code Online (Sandbox Code Playgroud)

还有val_callN一个接受任意数量的参数。请参阅此处声明

参考:https : //github.com/HaxeFoundation/hxcpp/blob/master/project/libs/std/Socket.cpp#L1039

方法2

幸运的是,当我搜索“ hxcpp val_call”(不带引号)时,只有3个结果,其中一个链接详细介绍了此方法。

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

免责声明

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