从 Haxe 传递给 C++ 的对象中的调用方法
Call method in object passed to C++ from Haxe
我正在为移动广告 SDK 创建 OpenFL 扩展,但我很难弄清楚一些 CFFI 内容。
基本上,我试图将一个 Haxe 对象传递给 C++,然后从 C++ 对该对象调用一个方法。这样做的目的是作为一个事件侦听器,所以当 C++ 中发生某些事情时,我将对该对象调用回调以通知 Haxe 代码。
我知道如何使用 Java 将 lime 的 JNI 东西用于 Android。使用 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"?
经过一番挖掘,我明白了!不幸的是,none 似乎完全记录了这一点,所以我想我会 post 在这里发现我的发现,以防其他人想做同样的事情。
方法一
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 中发生变化。我不知道。 ♂️
我正在为移动广告 SDK 创建 OpenFL 扩展,但我很难弄清楚一些 CFFI 内容。
基本上,我试图将一个 Haxe 对象传递给 C++,然后从 C++ 对该对象调用一个方法。这样做的目的是作为一个事件侦听器,所以当 C++ 中发生某些事情时,我将对该对象调用回调以通知 Haxe 代码。
我知道如何使用 Java 将 lime 的 JNI 东西用于 Android。使用 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"?
经过一番挖掘,我明白了!不幸的是,none 似乎完全记录了这一点,所以我想我会 post 在这里发现我的发现,以防其他人想做同样的事情。
方法一
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 中发生变化。我不知道。 ♂️