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

基于Emscripten将C++编译为WebAssembly并在React中嵌入的问题求助

解决React中嵌入WebAssembly(Wasm)的问题

核心问题定位

你当前的代码存在两个关键错误:

  1. JavaScript中错误调用了不存在的导出函数e(),但你的C++代码实际暴露的是add()
  2. 编译时使用了-s SIDE_MODULE=1参数——该参数用于动态链接的副模块,需要依赖主模块提供运行时环境,完全不适合独立调用的场景

修复方案(基于Emscripten)

1. 修正编译命令

移除SIDE_MODULE=1参数,改用适合独立运行的配置。推荐让Emscripten生成配套JS胶水代码(对新手更友好):

# 生成独立Wasm及配套胶水代码
em++ -std=c++17 test.cpp -Os -s WASM=1 -o add.js

# 若只想生成纯Wasm文件(无需胶水),使用:
# em++ -std=c++17 test.cpp -Os -s WASM=1 -s STANDALONE_WASM=1 -o add.wasm

2. 优化C++导出代码

现有代码基础上添加可见性标记,确保函数被正确导出(部分编译环境需要):

extern "C" {
    __attribute__((visibility("default")))
    int add(int x, int y) {
        return x + y;
    }
}

3. React中调用Wasm的两种方式

方式一:使用Emscripten胶水代码(最简单)

Emscripten生成的add.js会自动处理Wasm加载、实例化,直接引入即可:

import React, { useEffect } from 'react';

function Demo() {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = '/add.js';
    script.onload = () => {
      // 胶水代码会将模块挂载到window,函数名被处理为_add
      const result = window._add(2, 3);
      console.log('2+3计算结果:', result);
    };
    document.body.appendChild(script);

    return () => document.body.removeChild(script);
  }, []);

  return (
    <div>
      <p>WebAssembly嵌入测试</p>
      <p>打开控制台查看计算结果</p>
    </div>
  );
}

export default Demo;

方式二:手动加载纯Wasm文件(无胶水)

如果不想依赖Emscripten胶水,手动处理加载流程:

import React, { useEffect } from 'react';

function Demo() {
  useEffect(() => {
    const loadWasm = async () => {
      try {
        const response = await fetch('/add.wasm');
        const bytes = await response.arrayBuffer();
        const module = await WebAssembly.compile(bytes);
        // 独立Wasm无需额外导入对象,传空对象即可
        const instance = await WebAssembly.instantiate(module, {});
        
        const result = instance.exports.add(5, 7);
        console.log('5+7计算结果:', result);
      } catch (err) {
        console.error('Wasm加载失败:', err);
      }
    };

    loadWasm();
  }, []);

  return (
    <div>
      <p>WebAssembly嵌入测试</p>
      <p>打开控制台查看计算结果</p>
    </div>
  );
}

export default Demo;

多文件编译注意事项

如果要编译多个C++文件,直接将所有文件加入编译命令即可:

em++ -std=c++17 file1.cpp file2.cpp utils.cpp -Os -s WASM=1 -o app.js

替代工具(无需Emscripten时)

  • Binaryen:轻量级Wasm工具集,适合简单编译场景,但需手动处理更多底层细节
  • Wasmtime/WasmEdge:高性能Wasm运行时,适合需要扩展能力的场景,但React嵌入场景下Emscripten仍是最成熟的选择

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:15:20