Как создать объект C ++ в Duktape

Основывается на http://wiki.duktape.org/HowtoNativeConstructor.html, Я могу создать класс C ++ и экспортировать в JavaScript, код JavaScript также может создавать объекты

Но. когда я создаю объект в собственном коде c ++, он не может работать, код JavaScript не видит объект

Я получил сообщение об ошибке от Duktape:
«Ошибка типа: не удается прочитать свойство»

мой код:

class Btn
{
public:
void test()
{
printf("%s\r\n", __PRETTY_FUNCTION__);
}
};

Btn btn;

/* btn.prototype.test */
duk_ret_t btn_test(duk_context *ctx)
{
printf("%s\r\n", __PRETTY_FUNCTION__);

duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "\xff""\xff""Btn");
Btn *x = static_cast<Btn *>(duk_to_pointer(ctx, -1));
if (x)
{
x->test();
}
printf("Btn Addr 0x%08x\r\n", x);
duk_pop(ctx);

return 0;
}

duk_ret_t btn_destructor(duk_context *ctx)
{
printf("%s\r\n", __PRETTY_FUNCTION__);
return 0;
}

/* btn */
duk_ret_t btn_constructor(duk_context *ctx)
{
printf("%s\r\n", __PRETTY_FUNCTION__);

if (!duk_is_constructor_call(ctx))
{
return DUK_RET_TYPE_ERROR;
}

duk_push_this(ctx);

printf("Btn Addr 0x%08x\r\n", &btn);
duk_push_pointer(ctx, &btn);
duk_put_prop_string(ctx, -2, "\xff""\xff""Btn");

duk_push_c_function(ctx, btn_destructor, 1);
duk_set_finalizer(ctx, -2);

return 0;
}

void btn_init(duk_context *ctx)
{
duk_push_c_function(ctx, btn_constructor, 0);
duk_push_object(ctx);
duk_push_c_function(ctx, btn_test, 0);
duk_put_prop_string(ctx, -2, "test");
duk_put_prop_string(ctx, -2, "prototype");
duk_put_global_string(ctx, "Btn");
}

duk_ret_t getBtn(duk_context *ctx)
{
printf("%s\r\n", __PRETTY_FUNCTION__);

int n = duk_get_top(ctx);
if (n != 1)
{
return DUK_EXEC_ERROR;
}

// get "MyButton"std::string str(duk_to_string(ctx, 0));

// create Btn object
duk_get_global_string(ctx, "Btn");
duk_new(ctx, 0);

duk_push_object(ctx);

return DUK_EXEC_SUCCESS;
}

static duk_ret_t duk__print(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
printf("%s\n", duk_safe_to_string(ctx, -1));
return 0;
}

int main(int argc, char *argv[]) {

duk_context *ctx = duk_create_heap_default();

duk_push_c_function(ctx, duk__print, DUK_VARARGS);
duk_put_global_string(ctx, "print");

btn_init(ctx);

duk_push_global_object(ctx);
duk_push_c_function(ctx, getBtn, 1);
duk_put_prop_string(ctx, -2, "getBtn");
duk_pop(ctx);

printf("------- Script 1 -------\r\n");
{
std::string script1 = "btn = getBtn(\"MyButton\");" \
"print(btn);" \
"btn.test()";

duk_push_string(ctx, script1.c_str());
if (duk_peval(ctx) != 0)
{
printf("eval failed: %s\n", duk_safe_to_string(ctx, -1));
}

duk_pop(ctx);
}

printf("------- Script 2 -------\r\n");
{
std::string script2 = "btn = new Btn();" \
"print(btn);" \
"btn.test();";

duk_push_string(ctx, script2.c_str());
if (duk_peval(ctx) != 0)
{
printf("eval failed: %s\n", duk_safe_to_string(ctx, -1));
}

duk_pop(ctx);
}

duk_destroy_heap(ctx);

return 0;
}

выходной результат:

------- Сценарий 1 -------
duk_ret_t getBtn (duk_context *)
duk_ret_t btn_constructor (duk_context *)
Btn Addr 0x00476030
duk_ret_t btn_destructor (duk_context *)
не определено
Ошибка eval: TypeError: невозможно прочитать свойство 'test' из undefined
------- Сценарий 2 -------
duk_ret_t btn_constructor (duk_context *)
Btn Addr 0x00476030
[Объект Object]
duk_ret_t btn_test (duk_context *)
void Btn :: test ()
Btn Addr 0x00476030
duk_ret_t btn_destructor (duk_context *)

Как создать объект JavaScript в getBtn (Собственный код C ++), и вернуть объект в код JavaScript?

1

Решение

использование duk_new генерировать экземпляр класса JS из кода C ++. Этот вызов ожидает функцию конструктора и аргументы в стеке duk.

/* Assume target function is already on stack at func_idx.
* Equivalent to Ecmascript 'new func("foo", 123)'.
*/
duk_idx_t func_idx = /* ... */;

duk_dup(ctx, func_idx);
duk_push_string(ctx, "foo");
duk_push_int(ctx, 123);
duk_new(ctx, 2);  /* [ ... func "foo" 123 ] -> [ ... res ] */
printf("result is object: %d\n", (int) duk_is_object(ctx, -1));
duk_pop(ctx);
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector