在WebAssembly的C++代码中用embind给VideoDecoder传回调遇错求助
在WebAssembly的C++代码中实例化VideoDecoder的问题
背景
JS端初始化VideoDecoder的示例代码:
const decoder = new VideoDecoder({ output(frame) { renderFrame(frame); }, error(e) { setStatus("decode", e); } });
VideoDecoder构造函数签名:
const videoDecoder = new VideoDecoder({ output: processVideo, error: onEncoderError, });
尝试过程及错误
第一次尝试:使用自定义结构体
C++代码:
static void OnVideoFrame(emscripten::val frame) { } static void OnError(emscripten::val error) { } struct DecodeSettings_t { void (*output)(emscripten::val); void (*error)(emscripten::val); }; void VideoManager::Init(){ emscripten::val VideoDecoder = emscripten::val::global("VideoDecoder"); DecodeSettings_t set; set.output = &OnError; set.error = &OnVideoFrame; videoDecoderInst = VideoDecoder.new_(set); }
启动应用后报错:
{name: 'BindingError', message: 'parameter 0 has unknown type N2sn16DecodeSettings_tE', stack: 'BindingError: parameter 0 has unknown type ..}
第二次尝试:使用动态JS对象
改用动态创建JS对象传入构造函数:
emscripten::val obj = emscripten::val::object(); obj.set("output", &OnVideoFrame); obj.set("error", &OnError); videoDecoderInst = VideoDecoder.new_(obj);
出现新错误:
RuntimeError: Aborted(LinkError: WebAssembly.instantiate(): Import #116 module="env" function="_emval_new_object" error: function import requires a callable)
问题
请问我遗漏了什么?
解决方案
1. 结构体无法识别的原因
Emscripten无法自动将自定义C++结构体映射为JS对象,直接传递DecodeSettings_t会触发绑定错误,改用动态JS对象的方向是正确的。
2. _emval_new_object缺失的解决方法
这个错误说明编译时未启用Emscripten的embind模块,emscripten::val相关功能完全依赖该模块。你需要在编译命令中添加以下关键参数:
- 添加
--bind:启用embind绑定功能 - 添加
-lembind:链接embind库
示例编译命令:
emcc your_source.cpp -o output.js --bind -lembind
3. 额外注意事项
- 第一次尝试中
output和error的回调函数赋值写反了,正确的应该是set.output = &OnVideoFrame、set.error = &OnError,第二次尝试已修正,需确保逻辑正确。 - 回调函数需保证生命周期,使用
static函数可以避免局部函数被销毁的问题,当前代码的写法没问题。 - 如果后续遇到回调无法被JS正确调用的情况,可以用
emscripten::function包装C++函数后再赋值:
obj.set("output", emscripten::function(&OnVideoFrame)); obj.set("error", emscripten::function(&OnError));
内容的提问来源于stack exchange,提问作者Michael IV
相关产品推荐
相关产品推荐

