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

FlatBuffers与Duktape集成问题:JS到C++传递FlatBuffer失败求助

FlatBuffers与Duktape集成:JS到C++端Buffer验证失败的排查与修复

我之前在做Duktape和FlatBuffers的集成时也踩过类似的坑,结合你给出的代码来看,问题大概率出在参数索引错误和JS端Buffer封装这两个地方,咱们来一步步解决:

1. 核心问题:C端参数索引错误

你在JS里调用的是raise('log', new Buffer(fbb.asUint8Array())),这意味着传递给C端回调函数的是两个参数:第一个是字符串'log',第二个才是FlatBuffer的字节数据。

但你的C++代码里用了:

buff = duk_require_buffer_data(ctx, 1, &sz);

这里的索引1对应的是JS端传递的第一个参数(也就是'log'字符串),你拿到的其实是字符串的缓冲区,而不是FlatBuffer的数据,这肯定会验证失败!

修复方案:修正参数索引

把索引改成2,对应JS端的第二个参数:

void * buff;
duk_size_t sz;
// 索引改为2,指向传递的FlatBuffer数据
buff = duk_require_buffer_data(ctx, 2, &sz);
if (VerifyLogEventBuffer(flatbuffers::Verifier((uint8_t *)buff, (unsigned int)sz))) {
    std::cout << "Buffer is good here!" << std::endl;
} else {
    std::cout << "Buffer is broken here even" << std::endl;
}

2. 额外优化:JS端避免不必要的Buffer封装

你用new Buffer(fbb.asUint8Array())把FlatBuffer的原生Uint8Array包装成了Node.js风格的Buffer,但Duktape本身支持直接处理Uint8Array,额外的包装可能会引入不必要的结构(比如Buffer的内部元数据),反而干扰C端的读取。

优化方案:直接传递Uint8Array

修改JS端的代码,去掉new Buffer()的包装:

var fbb = new flatbuffers.Builder(1024);
PGS.Buffers.LogEvent.startLogEvent(fbb);
PGS.Buffers.LogEvent.addLevel(fbb,'WARN');
PGS.Buffers.LogEvent.addSource(fbb,"js");
PGS.Buffers.LogEvent.addText(fbb,"1 Event Emitted from JS now with a very long text string to make sure our buffer size increases.");
var toEmit = PGS.Buffers.LogEvent.endLogEvent(fbb);
PGS.Buffers.LogEvent.finishLogEventBuffer(fbb, toEmit);
print("1 Attempting to raise long log event using dataBuffer and Buffer");
// 直接传递原生Uint8Array
raise('log', fbb.asUint8Array());

验证步骤

你可以在C端打印sz的值,对比JS端fbb.size()的结果:

  • 如果修改前sz是3(对应'log'的长度),那说明确实是索引错误
  • 修改后sz应该和JS端的fbb.size()一致,此时验证大概率会成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:06:56