Hi Everyone,
If you have faced issues like me in finding concise tutorial on how to run C/C++ code in Deno using WASM, this is a to the point tutorial for you.
Prerequisites
- VSCODE: IDE
- Install WebAssembly plugin in VSCODE:
- EMSCRIPTEN Just follow each steps to install this tool.
- Deno
- C/C++ source code.
C Example
Step1: C Source code
We will use fairly simple code to demonstrate the concept.
We have a add.c
file which exposes a single function add
from it using emscriten macros.
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int add(int x, int y) {
return x + y;
}
Consider this as a facade for your C library.
Macro EMSCRIPTEN_KEEPALIVE from
emscripten.h
is required for all function you want to expose to be used in your Deno code.
Step2: Create WASM file
Run emscripten emcc
tool on your C file.
${EMSDK_HOME}/upstream/emscripten/emcc add.c -O3 --no-entry -o add.wasm
Explanation for the above command:
- -O3 WIll Optimize your WASM to best possible way. Used for production release.
- --no-entry flag is required as our code has no main function.
- -o will create an output file.
This will create a add.wasm
file.
Step3: Use WASM in DENO
I created a file usewasm.ts
:
//loads wasm file
export const f = await Deno.open("./add.wasm")
const buf = await Deno.readAll(f);
//load it as module
const wasmModule = new WebAssembly.Module(buf);
const wasmInstance = new WebAssembly.Instance(wasmModule);
//export the C functions in DENO!
const add = wasmInstance.exports.add as CallableFunction;
const subtract = wasmInstance.exports.subtract as CallableFunction;
//Use C functions
console.log(add(4,2));
Step4: Run the Deno code
deno run --allow-read usewasm.ts
- --allow-read : as our code will read wasm file
It should out put 6
.
C++ Example
Step1: C++ Source code
We will use fairly simple code to demonstrate the concept.
We have a mylib.cpp
file which exposes a two functions add
and subtract
from it using emscriten macros.
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int add(int x, int y) {
return x + y;
}
EMSCRIPTEN_KEEPALIVE
int subtract(int x, int y){
return x-y;
}
Consider this as a facade for your C++ library.
Macro EMSCRIPTEN_KEEPALIVE from
emscripten.h
is required for all function you want to expose to be used in your Deno code.
Step2: Create WASM file
Run emscripten emcc
tool on your C++ file.
${EMSDK_HOME}/upstream/emscripten/emcc mylib.c++ -O3 --no-entry -o mylib.wasm
Explanation for the above command:
- -O3 WIll Optimize your WASM to best possible way. Used for production release.
- --no-entry flag is required as our code has no main function.
- -o will create an output file.
This will create a mylib.wasm
file.
Step3: View generated wasm file.
If you have install the webassembly plugin mentioned in the pre-requisite, then you should see semthing like this after clicking Do you want to open it anyway?
.
Pay attention to _Z3addii
and _Z8subtractii
, this will be the name of the functions exported by your wasm. (Strange but in C++, unlike in C this exta prefix and suffix are added to your function name).
Step4: Use WASM in DENO
I created a file usewasm.ts
:
//loads wasm file
export const f = await Deno.open("./mylib.wasm");
const buf = await Deno.readAll(f);
//load it as module
const wasmModule = new WebAssembly.Module(buf);
const wasmInstance = new WebAssembly.Instance(wasmModule);
//export the C++ functions in DENO!: The function name can be seen in WASM file using VSCODE plugin
const add = wasmInstance.exports._Z3addii as CallableFunction;
const subtract = wasmInstance.exports._Z8subtractii as CallableFunction;
CallableFunction;
//Use C functions
console.log(add(4,2));
console.log(subtract(6,2));
Step5: Run the Deno code
deno run --allow-read usewasm.ts
- --allow-read : as our code will read wasm file
It should out put:
6
4
...
I have another reference sheet using WASI, instead of EMSCRIPTEN:
Use C/C++ code in DENO using WASM: In VSCODE, using WASI SDK
About WASI
What: WASI: Web assembly system interface.
Why: If your C/C++ code needs to make system call (say File IO, Socket, Clocks, Random numbers). Than you need WASI.
Top comments (0)