duktape js - 拥有多个具有自己全局的上下文并引用一个公共 'singleton'

duktape js - have multiple contexts with own global and reference to one common 'singleton'

我们正在将 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;
}

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

我们有一种方法,现在看来行之有效。使用

创建新上下文后
duk_push_thread_new_globalenv(master_ctx);
new_ctx = duk_require_context(master_ctx, -1);
duk_copy_element_reference(master_ctx, new_ctx, "ueber");

我们为在主上下文中创建的所有 properties/objects/functions 发出此调用序列:

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 有更深入了解的人可以对此发表评论?这是没有副作用的可行方案吗?

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