我为 OpenCPN 海上导航程序创建了一个插件,它结合了 Duktape 以提供脚本功能。OpenCPN 使用 wxWidgets。
基本上,该插件为用户提供了一个控制台,该控制台包括一个脚本窗口、一个输出窗口和各种按钮。用户输入他们的脚本(或从 .js 文件加载它)并单击运行。该脚本使用 duk_peval 运行。返回时,我会显示结果,销毁上下文并等待用户再次运行,可能是在修改脚本之后。这一切运作良好。但是,请考虑以下测试脚本:
add(2, 3);
function add(a, b){
if (a == b) throw("args match");
return(a + b);
}
如果 add 调用中的两个参数相等。该脚本会引发错误,用户可以重试。这一切都有效。
现在我可以将 add实现为 c++ 函数:
static duk_ret_t add(duk_context *ctx){
int a, b;
a = duk_get_int(ctx, 0);
b = duk_get_int(ctx, 1);
if (a == b){
duk_error(ctx, DUK_ERR_TYPE_ERROR, "args match");
}
duk_pop_2(ctx);
duk_push_int(ctx, a+b);
return (1);
}
如所写,这会将错误传递给致命错误处理程序。我知道我不能尝试进一步使用 Duktape,但我可以显示错误 OK。但是,我没有办法回到插件。规定的操作是退出或中止,但这些都终止托管应用程序,这是绝对不可接受的。理想情况下,我需要能够从 duk_peval 调用中返回错误。
我尝试使用来自外部 C++ 函数的 duk_pcall 运行 add 函数。这会捕获错误,我可以从该外部函数中显示它。但是当我从那个外部函数返回时,脚本在不应该的时候继续执行,并且从 duk_peval 调用的最终返回不知道错误。
我知道我可以在脚本中使用 try/catch,但可能会调用数十次 OpenCPN API,这是不现实的。将错误返回代码一直渗透回去,可能通过几个 C++ 函数,然后到顶层脚本也将非常麻烦,因为脚本和函数可能非常复杂。
谁能建议一种将控制权传回给我的调用插件的方法-最好是从 duk_peval 返回?