You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Duktape在C中定义JavaScript静态方法遇栈索引错误求助

问题

我想在类上定义一个静态方法,已有通过new实例调用方法的正常实现,但实现静态方法时出错。尝试的代码如下:

duk_push_c_function(ctx, call, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "call");
duk_put_prop_string(ctx, -2, "static");
duk_put_global_string(ctx, "JSONRPC2");

运行以下代码时:

duk_eval_string_noresult(ctx, "try { print('JSONRPC2 result: ' + JSONRPC2.call()) } catch(e) { print('Error: ' + e) }");

出现错误:

*** FATAL ERROR: uncaught: 'invalid stack index -2147483648'

补充说明:以下实例方法实现是可行的:

duk_push_c_function(ctx, jsonrpc_constructor, 0);
duk_push_bare_object(ctx);
duk_push_c_function(ctx, call, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "call");
duk_put_prop_string(ctx, -2, "prototype");
duk_put_global_string(ctx, "JSONRPC1");

duk_eval_string_noresult(ctx, "var rpc = new JSONRPC1; print('JSONRPC1 result: ' + rpc.call())");
解决方法

你的错误核心是没有先构造构造函数/类对象,就直接往不存在的栈元素上设置属性。

看可行的实例方法代码:先通过duk_push_c_function推出构造函数,再推一个空对象作为prototype,接着把方法挂到prototype上,最后把prototype挂到构造函数上,再设为全局变量。整个过程栈操作的索引都是有效的。

而你的静态方法代码里,第一步推了C函数后,直接执行duk_put_prop_string(ctx, -2, "call")——此时栈上只有这个C函数,索引-2根本不存在,这就导致了栈索引越界的致命错误。

要定义静态方法,需要先推出构造函数(类对象),然后把C函数作为属性直接挂到构造函数上,最后设为全局变量。修正后的代码如下:

// 1. 推出构造函数(类对象)
duk_push_c_function(ctx, jsonrpc_constructor, 0);
// 2. 推出要作为静态方法的C函数
duk_push_c_function(ctx, call, DUK_VARARGS);
// 3. 把这个C函数挂到构造函数的"call"属性上(静态方法)
duk_put_prop_string(ctx, -2, "call");
// 4. 将构造函数设为全局变量JSONRPC2
duk_put_global_string(ctx, "JSONRPC2");

这样修改后,JSONRPC2.call()就能正常调用静态方法了——因为静态方法是直接挂载在类(构造函数)本身上的属性,而不是prototype上。

内容的提问来源于stack exchange,提问作者Rodrigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:53:26