【问题标题】:Call method in object passed to C++ from Haxe从 Haxe 传递给 C++ 的对象中的调用方法
【发布时间】:2019-05-18 01:03:25
【问题描述】:

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

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

我知道如何在 Java 中使用 Lime 的 Android JNI 东西来做到这一点。使用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。

我知道从 Haxe 调用 C++ 函数的一般过程,使用 cpp.Lib.load 以类似于上面的 JNI api 的方式。但是,一旦我在 C++ 端获得了 value 类型,我不知道如何在其上调用成员函数。

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

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

我如何在listener 中调用函数“onSomething”?

【问题讨论】:

    标签: haxe openfl hxcpp


    【解决方案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

    方法二

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

    时,只有 3 个结果

    只需通读该线程以获得完整的解释。如果您需要更好的内存管理,该方法可能会更受欢迎,因为它还显示了如何从您的 C++ 绑定到 hxcpp GC。

    免责声明

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

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多