基于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*)
如何在 getBtn (C ++本机代码)函数中创建JavaScript对象,并将对象返回到JavaScript代码?
答案 0 :(得分:0)
使用duk_new从C ++代码生成JS类的实例。这个调用需要一个构造函数和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);