如何实现将数据写入C缓冲区以从JavaScript访问C结构体数据
从JavaScript访问WASM中C结构体数据:实现"read data into buffer"步骤
核心思路
要让JS访问C结构体,关键是把C结构体的二进制数据复制到WASM堆内存的缓冲区中,再让JS直接读取这块内存的二进制内容并解析。下面用具体代码示例拆解实现步骤:
1. C端代码:分配缓冲区并写入结构体数据
首先定义结构体,然后实现分配缓冲区、复制数据的函数:
#include <stdlib.h> #include <string.h> // 定义目标结构体 typedef struct { int id; float value; char name[16]; } MyStruct; // 模拟一个生成结构体数据的函数 MyStruct generate_struct() { MyStruct s; s.id = 123; s.value = 3.14f; strcpy(s.name, "demo_struct"); return s; } // 分配缓冲区并将结构体数据写入(核心的"read data into buffer"步骤) uint32_t get_struct_buffer() { MyStruct target = generate_struct(); // 分配能容纳一个MyStruct的堆内存 MyStruct* buffer = (MyStruct*)malloc(sizeof(MyStruct)); // 将结构体数据复制到缓冲区——这就是文档说的"read data into buffer" memcpy(buffer, &target, sizeof(MyStruct)); // 返回缓冲区指针(转成uint32_t方便JS接收) return (uint32_t)buffer; } // 提供结构体的字节大小,供JS解析用 uint32_t get_struct_byte_size() { return sizeof(MyStruct); } // 必须提供释放内存的函数,避免WASM内存泄漏 void free_buffer(uint32_t ptr) { free((void*)ptr); }
2. JavaScript端代码:读取并解析缓冲区数据
假设已经完成WASM模块的加载和实例化,代码如下:
// 从WASM实例中导出所需函数 const { get_struct_buffer, get_struct_byte_size, free_buffer } = wasmInstance.exports; // 获取缓冲区指针和结构体大小 const bufferPtr = get_struct_buffer(); const structSize = get_struct_byte_size(); // 从WASM内存中取出对应区域的字节数组 const wasmMemory = new Uint8Array(wasmInstance.exports.memory.buffer, bufferPtr, structSize); // 用DataView解析二进制数据(WASM默认小端字节序) const dataView = new DataView(wasmMemory.buffer, wasmMemory.byteOffset, wasmMemory.byteLength); // 按结构体字段的内存偏移解析数据 const id = dataView.getInt32(0, true); // int占4字节,偏移0 const value = dataView.getFloat32(4, true); // float占4字节,偏移4 const nameBytes = wasmMemory.slice(8, 8 + 16); // char数组占16字节,偏移8 const name = new TextDecoder().decode(nameBytes).trimEnd('\0'); // 去除字符串末尾的空终止符 // 输出解析结果 console.log("解析后的结构体数据:", { id, value, name }); // 最后务必释放缓冲区内存,避免泄漏 free_buffer(bufferPtr);
关键说明
- C端的
memcpy(buffer, &target, sizeof(MyStruct))就是"read data into buffer"的具体实现:把结构体的二进制内存内容完整复制到我们分配的堆缓冲区中。 - 如果要处理多个结构体,只需分配能容纳N个结构体的缓冲区,循环复制每个结构体的数据即可。
- JS端解析时要严格遵循C结构体的内存布局(字段偏移、类型字节大小),WASM的内存布局和标准C一致,注意字节序默认是小端。
内容的提问来源于stack exchange,提问作者redixhumayun
相关产品推荐
相关产品推荐

