gpt4 book ai didi

javascript - 如何在 Duktape 中创建 C++ 对象

转载 作者:太空宇宙 更新时间:2023-11-04 12:47:30 25 4
gpt4 key购买 nike

基于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;
}

输出结果:

------- Script 1 -------duk_ret_t getBtn(duk_context*)duk_ret_t btn_constructor(duk_context*)Btn Addr 0x00476030duk_ret_t btn_destructor(duk_context*)undefinedeval 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 0x00476030duk_ret_t btn_destructor(duk_context*)

如何在 getBtn(C++ 原生代码)函数中创建一个 JavaScript 对象,并将对象返回给 JavaScript 代码?

最佳答案

使用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);

关于javascript - 如何在 Duktape 中创建 C++ 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50713682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com