基于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;
}
输出结果:
-------- 脚本 1 -------- duk_ret_t getBtn(duk_context*) duk_ret_t btn_constructor(duk_context*) Btn 地址 0x00476030 duk_ret_t btn_destructor(duk_context*) 不明确的 评估失败:TypeError:无法读取未定义的属性“测试” ------- 脚本 2 ------- duk_ret_t btn_constructor(duk_context*) Btn 地址 0x00476030 [对象对象] duk_ret_t btn_test(duk_context*) 无效 Btn::test() Btn 地址 0x00476030 duk_ret_t btn_destructor(duk_context*)
如何在getBtn(C++ 本机代码)函数中创建 JavaScript 对象,并将对象返回给 JavaScript 代码?