0

我们正在将 JS 嵌入到我们的应用程序中,我们将使用几十个脚本,每个脚本都分配给一个事件。在这些脚本中,我们提供了一个最小的回调 api,

function onevent(value)
{ // user javascript code here
}

每当该事件发生时都会调用它。脚本必须有自己的全局,因为这个函数总是有相同的名称,我们从 cpp 代码访问它

duk_get_global_string(js_context_duk, "onevent");
duk_push_number(js_context_duk, val);
if (duk_pcall(js_context_duk, 1) != 0)
{
    printf("Duk error: %s\n", duk_safe_to_string(js_context_duk, -1));
}
duk_pop(js_context_duk);  /* ignore result */

再一次,我们希望允许脚本之间的最小通信,例如

脚本 1

var a = 1;
function onevent(val)
{
log(a);
}

脚本 2

function onevent(val)
{
 a++;
}

我们有没有办法做到这一点?也许通过引入一个自己的“ueber-”全局对象,它被定义一次并且在任何地方都可以引用?应该可以从任何脚本向这个“ueber-global object”添加属性,例如

脚本 1

function onevent(val)
{
log(ueber.a);
}

脚本 2

function onevent(val)
{
 ueber.a=1;
}
4

2 回答 2

0

您可以使用模块来代替简单的 JS 文件。duktape 附带了一个代码示例来实现一个模块系统(包括它的代码隔离),就像在 Node.js 中一样。有了它,您就可以导出应该可以共享的变量。

于 2021-09-04T08:17:58.530 回答
0

我们有一种现在似乎行得通的方法。在创建新上下文之后

duk_push_thread_new_globalenv(master_ctx);
new_ctx = duk_require_context(master_ctx, -1);
duk_copy_element_reference(master_ctx, new_ctx, "ueber");

我们为在主上下文中创建的所有属性/对象/函数发出这个调用序列:

void duk_copy_element_reference(duk_context* src, duk_context* dst, const char* element)
{
    duk_get_global_string(src, element);
    duk_require_stack(dst, 1);
    duk_xcopy_top(dst, src, 1);
    duk_put_global_string(dst, element);
}

它似乎有效(因为一切都在同一个堆中,而且都是单线程的)。也许对 duktape 有更深入了解的人可以对此发表评论?这是一个没有副作用的可行解决方案吗?

编辑:将此标记为答案。按预期工作,没有内存泄漏或其他问题。

于 2021-09-04T19:13:14.507 回答