用Emscripten编译C++到WASM后,如何正确导出和调用带std::string参数的函数?

___誉馨 阅读 2

我用Emscripten把一段C++代码编译成WASM,里面有个函数接收std::string参数,但在JS里调用时总是报错或者传参不对。查了文档说要处理内存分配,但具体该怎么做?

我的C++函数大概是这样的:

#include <string>
extern "C" {
  void processText(std::string input) {
    // 处理字符串
  }
}

编译命令用了emcc -O2 --bind -s EXPORTED_FUNCTIONS='["_processText"]',但JS里不知道怎么传字符串进去,直接传JS字符串会崩溃。

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
爱欢
爱欢 Lv1
这个问题很典型,用--bind编译的话得用embind来导出函数,光导出函数名是不够的。

C++代码改成这样:

#include <string>
#include <emscripten/bind.h>

using namespace emscripten;

void processText(std::string input) {
// 直接用input,它是std::string
}

EMSCRIPTEN_BINDINGS(my_module) {
function("processText", &processText);
}


编译命令:

emcc -O2 --bind input.cpp -o output.js


不需要再手动写EXPORTED_FUNCTIONS了,--bind会帮你处理。

JS调用:

const Module = require('./output.js');

Module.onRuntimeInitialized = function() {
// 直接传JS字符串就行,embind自动转换
Module.processText("hello from js");
};




如果你坚持不用embind,想直接操作内存也行,但得这么搞:

C++保持原样,编译时去掉--bind:

emcc -O2 -s EXPORTED_FUNCTIONS='["_processText"]' -s EXPORTED_RUNTIME_METHODS='["UTF8ToString"]' input.cpp -o output.js


JS端手动分配内存传过去:

const str = "hello from js";
const len = Module.lengthBytesUTF8(str) + 1;
const ptr = Module._malloc(len);
Module.stringToUTF8(str, ptr, len);
Module._processText(ptr);
Module._free(ptr); // 用完记得释放


但这种写法容易漏内存,个人建议直接用embind,省心。
点赞
2026-03-12 21:29