Wasm数据无法在HTML Canvas渲染,请求排查故障
问题排查与修复方案
1. 文件名不匹配
你的HTML代码中加载的是fizzbuzz.wasm,但Makefile生成的Wasm文件是display.wasm,这会导致加载的模块错误或找不到正确文件。修改HTML中的fetch路径:
WebAssembly.instantiateStreaming(fetch('display.wasm'), importObject)
2. 颜色数组初始值全透明
C代码中int screen[57600]默认初始化为0,对应RGBA值是rgba(0,0,0,0),完全透明,所以渲染后看不到任何内容。需要给数组填充可见颜色:
- 方案一:在C中初始化数组(以红色为例)
#include <string.h> void print(int val); int screen[57600]; void init_screen() { // 填充红色:0xFF0000FF(RGBA字节序) for (int i = 0; i < 57600; i++) { screen[i] = 0xFF0000FF; } } int* get_screen(){ print(1); init_screen(); return &screen[0]; }
- 方案二:在JS中临时修改数组测试
// 获取display数组后,先填充测试颜色 for (let i = 0; i < display.length; i++) { display[i] = 0xFF0000FF; // 红色 }
3. 废弃的arguments.callee用法
arguments.callee在严格模式下已被废弃,替换为命名函数实现递归渲染:
function renderLoop() { for (let i = 0; i < display.length; i++) { // 原有渲染逻辑不变 const uint32 = display[i]; const r = (uint32 >> 24) & 0xFF; const g = (uint32 >> 16) & 0xFF; const b = (uint32 >> 8) & 0xFF; const a = uint32 & 0xFF; const x = i % 360; const y = Math.floor(i / 360); ctx.fillStyle = `rgba(${r},${g},${b},${a})`; ctx.fillRect(x, y, 1, 1); } requestAnimationFrame(renderLoop); } requestAnimationFrame(renderLoop);
4. 可选优化:使用ImageData提升渲染效率
逐个调用fillRect效率极低,改用ImageData直接操作画布像素:
const imageData = ctx.createImageData(canvas.width, canvas.height); const data = imageData.data; function renderLoop() { for (let i = 0; i < display.length; i++) { const uint32 = display[i]; data[i*4] = (uint32 >> 24) & 0xFF; // R data[i*4+1] = (uint32 >> 16) & 0xFF; // G data[i*4+2] = (uint32 >> 8) & 0xFF; // B data[i*4+3] = uint32 & 0xFF; // A } ctx.putImageData(imageData, 0, 0); requestAnimationFrame(renderLoop); } requestAnimationFrame(renderLoop);
验证步骤
- 重新编译Wasm:执行
make display.wasm - 启动本地服务:
make run_wasm - 打开浏览器访问
http://127.0.0.1:8000,查看画布是否显示内容
内容的提问来源于stack exchange,提问作者Junus Safsouf
相关产品推荐
相关产品推荐

