讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何调用WebAssembly模块?(Emscripten集成)

秋瑶姑娘_2754

秋瑶姑娘_2754

发布时间:2026-02-26 13:53:02

|

608人浏览过

|

来源于php中文网

原创

C++无法直接调用Wasm函数,必须通过Emscripten生成的JS胶水层中转;需用EMSCRIPTEN_KEEPALIVE标记导出函数,限定为C ABI和基础类型,并配合EXPORTED_FUNCTIONS指定导出名。

c++如何调用webassembly模块?(emscripten集成)

如何从C++代码里调用已编译的Wasm函数?

Emscripten生成的Wasm模块默认不暴露C++符号给宿主JS,反过来,C++主程序也不能直接“链接”外部Wasm二进制——它根本不是传统意义上的动态库。真正可行的路径是:让Wasm模块导出函数,再通过Emscripten自动生成的JS胶水代码(Module)把它们桥接到C++侧。

  • 必须用EMSCRIPTEN_KEEPALIVE宏标记要导出的C++函数,否则会被Link Time Optimization(LTO)干掉
  • 导出函数只能使用C ABI(即extern "C"),不能带重载、模板或std::string等非POD类型
  • 所有参数和返回值需是基础类型(int、float、const char*等),字符串需手动管理内存生命周期

例如,在Wasm模块中写:

#include <emscripten.h>
extern "C" {
  EMSCRIPTEN_KEEPALIVE
  int add(int a, int b) { return a + b; }
}
编译时加-s EXPORTED_FUNCTIONS='["_add"]',才能确保_add出现在Module._add上。

为什么C++主程序不能直接dlopen或LoadLibrary加载.wasm文件?

Wasm不是ELF或PE格式,操作系统加载器根本不认识它。浏览器和Node.js里的Wasm运行时(如V8、SpiderMonkey)是独立实现的执行环境,和本地进程的地址空间、调用约定、异常机制完全隔离。

  • .wasm文件本质是字节码,必须由Wasm虚拟机实例化后才能执行,无法像.so那样被dlopen映射进当前进程
  • 即使你用std::ifstream读取了.wasm二进制,也没法靠C++原生代码“调用”它——缺少执行上下文、内存视图、导入表绑定等基础设施
  • Emscripten的EM_ASM或EM_ASM_INT可以嵌入JS逻辑,但那是把控制权交还给JS运行时,不是C++直调Wasm

换句话说:C++调Wasm ≠ C++调DLL;它是“C++ → JS胶水层 → Wasm实例”,中间那层JS绕不开。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

EM_ASM和EM_JS哪个更适合触发Wasm导出函数?

EM_JS用于声明JS函数供C++调用,适合封装复杂逻辑;EM_ASM是内联JS片段,适合简单、一次性的调用。

  • 如果只是传两个整数、拿一个返回值,用EM_ASM_INT({ return Module._add($0, $1); }, a, b)最轻量
  • 如果要多次调用、处理指针(比如传入uint8_t*数组)、或需要错误检查,应先用EM_JS定义一个JS wrapper,再在C++里调它
  • 注意$0、$1是EM_ASM里的占位符,对应后续参数,类型自动转为JS可接受形式(int变number,char*变JS string,但会拷贝)
  • 指针操作危险:EM_ASM里拿到的char*是Wasm线性内存地址,JS侧不能直接解引用,必须配合HEAP8等视图访问

比如传数组:

EM_ASM({
  const ptr = $0;
  const len = $1;
  for (let i = 0; i < len; ++i) {
    console.log(HEAP8[ptr + i]);
  }
}, arr_ptr, arr_len);

常见报错Module._xxx is not a function怎么定位?

这个错误90%是因为导出没生效,而不是JS加载失败。

  • 检查编译命令是否含-s EXPORTED_FUNCTIONS='["_xxx"]',且函数名带下划线(C++函数add导出后是_add)
  • 确认EMSCRIPTEN_KEEPALIVE已包含在函数定义中,且头文件<emscripten.h></emscripten.h>已引入
  • 在浏览器Console里打印Object.keys(Module),看_xxx是否在列表里;如果不在,说明链接阶段已被strip
  • 如果用了-O2或更高优化级,务必加--no-file-system --no-entry等精简选项,避免Emscripten自动裁剪未引用符号

最容易被忽略的是:C++源码改了,但忘了重新emcc编译生成新的.js和.wasm——旧JS胶水代码根本不知道新函数存在。

热门AI工具

更多
立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7259

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

7447

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

864

2025.10.23

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2398

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1898

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3084

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6324

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6369

2023.11.24

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn