Вызов метода в объекте, переданном в C ++ из Haxe - PullRequest
3 голосов
/ 18 мая 2019

Я создаю расширение OpenFL для SDK для мобильной рекламы, и мне трудно разобраться в некоторых вещах CFFI.

По сути, я пытаюсь передать объект Haxe в C ++, а затемвызовите метод этого объекта из C ++.Цель этого заключается в том, чтобы прослушивать события, поэтому, когда что-то происходит в C ++, я буду вызывать функцию обратного вызова для этого объекта, чтобы уведомить код Haxe.Android.Это выглядит примерно так, используя сигнатуры типа 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

Затем со стороны Java я могу вызвать функцию onSomething следующим образом:

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

И это работает, и это то, как я делаю это для Android.Для iOS я пытаюсь сделать то же самое, но с hxcpp.

Я знаю общий процесс вызова функции C ++ из Haxe, используя cpp.Lib.load аналогично API JNI, описанному выше.Однако, как только я получаю тип value на стороне C ++, я не знаю, как я могу вызвать функцию-член для него. Например,

, скажем, моя функция C ++ выглядит так:

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

Как мне тогда вызвать функцию "onSomething" в listener?

1 Ответ

3 голосов
/ 21 мая 2019

После некоторых раскопок я понял это!К сожалению, ничего из этого, похоже, не задокументировано, поэтому я решил опубликовать свои выводы здесь на тот случай, если кто-то захочет сделать то же самое.

Метод 1

hxcpp CAPI, по-видимому, очень похож на Neko, но не совсем то же самое.Тем не менее, документация Neko является хорошей отправной точкой.

На этой странице показано, как вызвать функцию с помощью 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, который принимает произвольное количество аргументов.См. Объявление здесь .

Ссылка: https://github.com/HaxeFoundation/hxcpp/blob/master/project/libs/std/Socket.cpp#L1039

Метод 2

К счастью, было только 3 результата, когда я гуглил "hxcpp val_call"( без кавычек) и одна из этих ссылок подробно описывает этот метод.

Просто прочитайте эту ветку для полного объяснения.Этот метод, вероятно, предпочтительнее, если вам нужно более эффективное управление памятью, так как он также показывает, как подключиться к hxcpp GC из вашего C ++.

Отказ от ответственности

Я не смог найти никакой реальной документациина val_id и val_field, поэтому возможно, что эти методы не предназначены для внешнего использования и могут измениться в более поздней версии hxcpp.Я понятия не имею.?♂️

...