Use C/C++ code in DENO using WASM: In VSCODE, using Emscripten
Tags: deno, javascript, typescript, webassembly
Published: 2021-04-06 04:32:41

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](https://marketplace.visualstudio.com/items?itemName=dtsvet.vscode-wasm) in VSCODE:
3. [EMSCRIPTEN](https://emscripten.org/docs/getting_started/downloads.html)
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.

```c
#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](https://emscripten.org/docs/api_reference/emscripten.h.html#c.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`:
```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
[GIT for C++ code](https://github.com/anuragvohraec/EXAMPLE_CPP_WASM_DENO.git)

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

```c
#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](https://emscripten.org/docs/api_reference/emscripten.h.html#c.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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24lyor5tvp1k94cgcda7.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohlqmj8rijrjembxjqq5.png)
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`:
```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](https://dev.to/anuragvohraec/use-c-c-code-in-deno-using-wasm-in-vscode-using-wasi-sdk-29d5)
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.