На основе http://wiki.duktape.org/HowtoNativeConstructor.html, Я могу создать класс c ++ и экспортировать в JavaScript, код JavaScript также может создавать объекты
Но.когда я создаю объект в собственном коде c ++, он не может работать, код JavaScript не видит объект
Я получил сообщение об ошибке от Duktape: «TypeError: не удается прочитать свойство»
мой код:
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;
}
результат вывода:
------- Script 1 -------
duk_ret_t getBtn(duk_context*)
duk_ret_t btn_constructor(duk_context*)
Btn Addr 0x00476030
duk_ret_t btn_destructor(duk_context*)
undefined
eval failed: TypeError: cannot read property 'test' of undefined
------- Script 2 -------
duk_ret_t btn_constructor(duk_context*)
Btn Addr 0x00476030
[object 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?