Running WebAssembly from any language

Wasmer now offers a C API for its WebAssembly runtime.

Using the new Wasmer C bindings, it is now possible to run WebAssembly code from a variety of programming languages that support calling C APIs including C, C++, Python, PHP and many more!

In this article, we will make a simple wasm application using C and Emscripten and then run it using the Wasmer runtime C bindings.

This tutorial was adapted from our previous example tutorial embedding in a Rust application.

WebAssembly Sample Application

We will create a sample application that prints “Hello, World!”.

Because WebAssembly doesn’t inherently have any way to print to standard output, we have to import a function from the host environment, print_str , which takes an index to a string in the linear memory and its length.

This allows us to read the memory and print the string.

We will compile this C application to wasm using Emscripten:

emcc source.c -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS="['_hello_wasm']" -o target.wasm

Wasmer C API Example Application

The following section shows how to use Wasmer’s C API to define imports including a host function, instantiate a wasm app, and call one of its exported functions.

First, include the wasmer.h header file from the wasmer-runtime-c-api library:

Next, define a host function that will be imported into the Web Assembly Instance:

Also, define a print_wasmer_errorhelper function to print error messages from thewasmer_last_error* APIs:

The main function below will use the Wasmer C API to instantiate and run the WebAssembly example program.

Define the import function which provides a function pointer for our print_str method to be called from our wasm program:

Create module name for our imports represented in UTF-8 bytes for wasm compatibility. Then, define the memory, global, and function imports needed by the sample program:

With the imports defined, we can read the wasm bytes and instantiate the wasm program:

Last, we call the exported _hello_wasm function which will call the print_str host function with an index and length that indicate the location in the memory of the Hello, World! bytes to print:

After using the pointers provided by the API, we cleaned them up using the wasmer_*_destroy methods as described in the header documentation.

For more example usages and documentation, take a look at the C API tests and the wasmer.h header file.

The full source for this example post is hosted on Github. If you have feedback, issues, or feature requests please open an issue in the Wasmer Github repo.

The Wasmer team is also available on Spectrum chat to answer any questions.

Happy hacking!