DEV Community

loading...
Cover image for Use C/C++ code in DENO using WASM: In VSCODE, using Emscripten

Use C/C++ code in DENO using WASM: In VSCODE, using Emscripten

anuragvohraec profile image Anurag Vohra ・3 min read

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

  1. VSCODE: IDE
  2. Install WebAssembly plugin in VSCODE:
  3. EMSCRIPTEN Just follow each steps to install this tool.
  4. Deno
  5. 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;
}
Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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

GIT for C++ code

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;
}
Enter fullscreen mode Exit fullscreen mode

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.

image

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?.

image
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));
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

...
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.

Discussion (0)

pic
Editor guide