基于Emscripten的C++ WebAssembly JSON写入及浏览器动态更新问询
当然可以实现!咱们一步步来搞定这个需求——从让WASM把键值数据传给JS,到动态更新浏览器视图,再到生成JSON文件,都有清晰的方案:
1. 让C++ WASM把键值对传递到JavaScript
有两种常用方式,优先推荐直接调用JS函数(比解析stdout输出更高效、更可靠):
方式一:直接在C++中调用JS函数
用Emscripten的EM_ASM宏,在C++代码里直接触发JS的全局函数来传递键值:
#include <emscripten.h> #include <cstdio> // 封装一个向JS发送键值对的C++函数 void sendKeyValue(const char* key, const char* value) { EM_ASM({ // $0、$1对应C++传入的key和value参数,转成JS字符串 const jsKey = UTF8ToString($0); const jsValue = UTF8ToString($1); // 调用JS全局函数处理数据 window.updateKeyValue(jsKey, jsValue); }, key, value); } // 模拟每秒生成数据的逻辑 void generateData() { static int counter = 0; char key[30], value[30]; sprintf(key, "sample-key-%d", counter); sprintf(value, "%d", counter++); // 发送键值对到JS sendKeyValue(key, value); // 每秒递归调用自己,持续生成数据 emscripten_set_timeout(generateData, 1000); } int main() { // 启动数据生成(延迟1秒第一次执行) emscripten_set_timeout(generateData, 1000); return 0; }
方式二:解析stdout输出(适配已有的printf代码)
如果你的C++代码已经通过printf("some-key:some-value\n")输出数据,那可以在JS里重定向stdout的处理函数,自动解析每行的键值:
// 重定向Emscripten的stdout输出 Module.print = function(text) { const line = text.trim(); if (!line) return; // 按冒号拆分键值 const [key, value] = line.split(':'); if (key && value) { updateKeyValue(key.trim(), value.trim()); } };
2. 在JS中维护数据并每秒更新视图
接下来在JS里维护一个全局对象存储数据,再用setInterval定时更新页面视图:
// 用来存储所有键值对的对象(最终可以转成JSON) const appData = {}; // 处理从WASM传来的键值对 function updateKeyValue(key, value) { appData[key] = value; } // 每秒更新浏览器视图的函数 function refreshView() { // 把数据转成格式化的JSON字符串 const formattedJson = JSON.stringify(appData, null, 2); // 更新页面上的DOM元素(比如用<pre>标签展示JSON) const displayElement = document.getElementById('json-display'); if (displayElement) { displayElement.textContent = formattedJson; } } // 启动每秒更新任务 setInterval(refreshView, 1000);
对应的HTML展示区域:
<pre id="json-display"></pre>
3. 生成JSON文件供下载
如果需要把当前的JSON数据保存为本地文件,可以添加一个下载功能:
function downloadJsonFile() { const jsonStr = JSON.stringify(appData, null, 2); // 创建Blob对象 const blob = new Blob([jsonStr], { type: 'application/json' }); const url = URL.createObjectURL(blob); // 创建临时下载链接 const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = 'app-data.json'; downloadLink.click(); // 释放URL资源 URL.revokeObjectURL(url); } // 绑定到按钮点击事件 document.getElementById('download-btn').addEventListener('click', downloadJsonFile);
对应的HTML按钮:
<button id="download-btn">下载JSON</button>
编译注意事项
编译C++代码时,要确保导出必要的函数和运行时方法:
emcc your-code.cpp -o your-code.js -s EXPORTED_FUNCTIONS='["_main", "_generateData"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["UTF8ToString", "emscripten_set_timeout"]'
内容的提问来源于stack exchange,提问作者KaviKumar N
相关产品推荐
相关产品推荐

