emscripten 中c 代码引用外部js 函数

发布时间 2023-11-28 18:54:35作者: 荣锋亮

主要是一个简单的学习,webassebly 支持通过import 调用环境的函数(比如调用浏览器或者nodejs 中的一些方法)

简单说明

方法很多,包含了emscripten 提供的调用js 的宏,但是以下使用了一个emscripten 提供的--js-library 功能

  • --js-library 简单说明
    --js-library 主要是实现emcc 在编译的时候使用外部js 提供的方法,同时--js-library 对于外部库的定义也有一些要求
    参考格式
 
addToLibrary({
  my_js: function() {
    alert('hi');
  },
});
  • 项目使用
    jsapp.c
 
#include <emscripten.h>
// 通过extern 定义引用外部的js 方法,编译的时候通过--js-library 指定外部方法的实现
extern int sub(int a, int b);
EMSCRIPTEN_KEEPALIVE
int subapp(int a, int b){
    return sub(a,b);
}

cmake 构建target(为了简单我使用了一个绝对路径的地址)

add_executable(jssub src/jsapp.c)
target_link_libraries(jssub "-s MODULARIZE=1 --js-library /src/${CMAKE_CURRENT_SOURCE_DIR}/sub_library.js -s EXPORTED_RUNTIME_METHODS=ccall")

构建

基于容器构建

  • 构建命令
docker run -it -v $PWD:/src  emscripten/emsdk:3.1.47 sh
mkdir build
cd build 
emcmake cmake ..
make 
  • 效果

 

  • 代码调用
const jssub = require("./build/jssub")
jssub().then((instance) => {
  console.log(instance._subapp(33,1))
})

说明

代码已经push 到gihtub了,可以参考, 核心是参考emscripten提供的格式要求,但是此方法是有一些限制的(不能使用闭包,解决方法是使用
--pre-js 或者--post-js )

参考资料

https://github.com/rongfengliang/emscripten_basic_learning
https://web.dev/articles/emscripten-embedding-js-snippets?hl=zh-cn
https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#implement-c-in-javascript