Hi Everyone,
In my previous post : Use C/C++ code in DENO using WASM: In VSCODE, using Emscripten, I used Emscripten to convert C/C++ code to WASM and then use it in Deno. Here we will use 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.
- How: Follow the instructions below.
Prerequisite
- VSCODE: IDE
- Install WebAssembly plugin in VSCODE:
- WASI SDK Download the latest tar.gz file and extract to directory of your choice, we will call it WASI_SDK_HOME.
- Deno
- C/C++ source code
C++ Example
Step1: Your C++ Source code.
I have named my C++ code file as app.cpp \
Its a Simple C++ code to create a copy of file based on the run time arguments passed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <iostream>
int main(int argc, char **argv) {
ssize_t n, m;
char buf[BUFSIZ];
if (argc != 3) {
fprintf(stderr, "usage: %s <from> <to>\n", argv[0]);
exit(1);
}
int in = open(argv[1], O_RDONLY);
if (in < 0) {
fprintf(stderr, "error opening input %s: %s\n", arhttps://github.com/anuragvohraec/EXAMPLE_WASI_CPP_DENOhttps://github.com/anuragvohraec/EXAMPLE_WASI_CPP_DENOgv[1], strerror(errno));
exit(1);
}
int out = open(argv[2], O_WRONLY | O_CREAT, 0660);
if (out < 0) {
fprintf(stderr, "error opening output %s: %s\n", argv[2], strerror(errno));
exit(1);
}
while ((n = read(in, buf, BUFSIZ)) > 0) {
char *ptr = buf;
while (n > 0) {
m = write(out, ptr, (size_t)n);
if (m < 0) {
fprintf(stderr, "write error: %s\n", strerror(errno));
exit(1);
}
n -= m;
ptr += m;
}
}
if (n < 0) {
fprintf(stderr, "read error: %s\n", strerror(errno));
exit(1);
}
std::cout << "Done" << std::endl;
return EXIT_SUCCESS;
}
Step2: Compile it to wasm using WASI SDK
Lets say you have extracted your WASI SDK tar.gz
in ~/wasm-sdk-vers
folder we will call it WASI_SDK_HOME in the code below.
You can compile the C++ code to wasm using below command.
`${WASI_SDK_HOME}/bin/clang++ app.cpp --sysroot=${WASI_SDK_HOME}/share/wasi-sysroot -o app.wasm`
This will output app.wasm
file.
Step3: Use wasm in deno
Deno file name is test_app.ts
//this standard modoule is required to run wasi code: it provide system calls needed by WASI
import Context from "https://deno.land/std@0.92.0/wasi/snapshot_preview1.ts";
//Create context
const context = new Context({
args: Deno.args, //args will be the run time argument passed to WASM code
env: Deno.env.toObject(), //Any environment varibale you wanted to pass
preopens: {"./":"./"} //Directories which will be hosted in WASI Sandbox to be used by WASM. The string keys of are treated as directories within the sandboxed filesystem, the values are the real paths to those directories on the host machine.
});
const binary = await Deno.readFile("app.wasm");
const module = await WebAssembly.compile(binary);
const instance = await WebAssembly.instantiate(module, {
"wasi_snapshot_preview1": context.exports,
});
context.start(instance);
Step4: Run the code:
deno --unstable run -A test_app.ts app.wasm README.md cr.md
I have readme.md file which I want to copy and create cr.md file.
It should output:
Done
#And create a cr.md file in the directory
Top comments (0)