Show / Hide Table of Contents

Introduction to .NET embedding of Wasmtime

Wasmtime is a standalone runtime capable of executing WebAssembly outside of a web browser.

The .NET embedding of Wasmtime enables .NET developers to easily instantiate and execute WebAssembly modules using Wasmtime.

For this tutorial, we will create a WebAssembly module and use that WebAssembly module from a .NET 5 application.

A simple WebAssembly module

One of the reasons why WebAssembly is so exciting is that many languages are able to target WebAssembly. This means, for example, a plugin model based on WebAssembly could enable developers to write sandboxed, cross-platform plugins in any number of languages.

For this introduction, however, we will use a WebAssembly module in WebAssembly Text Format:

(module
  (func $hello (import "" "hello"))
  (func (export "run") (call $hello))
)

This module simply imports a hello function from the host and exports a run function that calls the imported function.

Using the WebAssembly module from .NET

Installing a .NET 5 SDK

Install a .NET 5 SDK for your platform if you haven't already.

This will add a dotnet command to your PATH.

Creating the .NET project

The .NET program will be a simple console application, so create a new console project with dotnet new:

mkdir tutorial
cd tutorial
dotnet new console

Referencing the Wasmtime package

To use the .NET embedding of Wasmtime from the project, we need to add a reference to the Wasmtime NuGet package:

dotnet add package wasmtime

This will add a PackageReference to the project file so that .NET embedding for Wasmtime can be used.

Implementing the .NET code

Replace the contents of Program.cs with the following:

using System;
using Wasmtime;

namespace Tutorial
{
    class Program
    {
        static void Main(string[] args)
        {
            using var engine = new Engine();

            using var module = Module.FromText(
                engine,
                "hello",
                "(module (func $hello (import \"\" \"hello\")) (func (export \"run\") (call $hello)))"
            );

            using var linker = new Linker(engine);
            using var store = new Store(engine);

            linker.Define(
                "",
                "hello",
                Function.FromCallback(store, () => Console.WriteLine("Hello from C#!"))
            );

            var instance = linker.Instantiate(store, module);
            var run = instance.GetAction(store, "run");
            run();
        }
    }
}

The Linker class is responsible for linking in those defined functions, such as hello in this example.

Here we are defining a function named hello that simply prints Hello from C#! when called from WebAssembly.

A WebAssembly module instantiation is the stateful representation of a module that can be executed.

This code is calling the run function defined in WebAssembly that is exported by the instance; this function then calls the hello function defined in C#.

Building the .NET application

Use dotnet build to build the .NET application:

dotnet build

This will create a tutorial (or tutorial.exe on Windows) executable in the bin/Debug/net5.0 directory that implements the .NET application.

Running the .NET application

To run the .NET application, simply invoke the executable file or use dotnet:

dotnet run

This should result in the following output:

Hello from C#!
  • Improve this Doc
In This Article
Back to top Generated by DocFX