Blog Entry

记录C转Wasm的一次尝试

记录C转Wasm的一次尝试

Created
2022/02/02
Updated
2022/02/02

安装emsdk

Terminal window
# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git
# Enter that directory
cd emsdk
Terminal window
# Fetch the latest version of the emsdk (not needed the first time you clone)
git pull
# Download and install the latest SDK tools.
./emsdk install latest
# Make the "latest" SDK "active" for the current user. (writes .emscripten file)
./emsdk activate latest
# Activate PATH and other environment variables in the current terminal
# linux
source ./emsdk_env.sh
# windows
emsdk_env.bat

./emsdk install latest过程中,会自动安装node,python,jre,以及emscripten.

吓得我马上开了个命令行确认一下:

Terminal window
node -v
python -V
java -version

并没有改掉我的环境,看来是安装的Portable版本.

./emsdk activate latest之后,则会修改PATH,EMSDK, EM_CONFIG, EMSDK_NODE, EMSDK_PYTHON, JAVA_HOME环境变量.

看来受影响的是Java,同时修Java的同学需要留意.

到此,获得emccem++, 可以类比为gccg++.

编译样例代码

  • 代码
main.c
#include <stdio.h>
int main() {
printf("hello, world!\n");
return 0;
}
  • 编译
Terminal window
emcc main.c
  • 生成

    • main.js
    • main.wasm
    • main.html
  • 查看

    • 启动一个本地http服务,以8080为访问端口.
    • 访问http://localhost:8080/main.html

调用C方法

导出函数

EMSCRIPTEN_KEEPALIVE

  • 代码级别的控制
  • 在需要到处的函数使用EMSCRIPTEN_KEEPALIVE
#include <emscripten/emscripten.h>
int EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) {
printf("我的函数已被调用\n");
}

这里需要指定emscripten的头文件目录:$(EMSDK)\upstream\emscripten\system\include

EXPORTED_FUNCTIONS

  • 编译级别的控制
emcc -s EXPORTED_FUNCTIONS=foo,bar
  • 示例
Terminal window
# 使用自定义html模板
emcc ..\function\main.c -o ./out/func.html --shell-file=..\function\template.html -s EXPORTED_RUNTIME_METHODS=ccall -s EXPORTED_FUNCTIONS=_main,_xkFunc
# 仅导出js
emcc ..\function\main.c -o ./out/func.js -s EXPORTED_RUNTIME_METHODS=ccall -s EXPORTED_FUNCTIONS=_main,_xkFunc

资料