How does c# use WASM to call across languages?

Introducing Wasm (WebAssembly)

WebAssembly (Wasm for short) is a binary instruction format for stack-based virtual machines. Wasm is designed as a portable compilation target for programming languages ​​that support the deployment of client and server applications on the web.

What is wasmtime (WebAssembly Time)? What is its relationship with WASM (WebAssembly)?

wasmtimeis a standalone, lightweight WebAssembly (WASM) runtime that supports WASI (WebAssembly System Interface). wasmtimeDeveloped by the Bytecode Alliance, an alliance dedicated to creating new software infrastructures that enable modular, composable, secure and efficient software.

wasmtimeThe relationship with WASM (WebAssembly) is as follows:

  1. WebAssembly runtime : wasmtimeis a runtime that allows you to execute WebAssembly code in your local environment without the need for a browser. This means that you can wasmtimerun any code compiled to WASM, whether compiled from C, Rust, Go, or another language, using .

  2. WASI Support : wasmtimeis a primary implementation of WASI, meaning it can run WebAssembly programs that use the WASI interface, allowing those programs to access files, networks, and other system resources.

  3. Security : Like WebAssembly, wasmtimeit also provides a sandbox environment to ensure that WASM code runs in a restricted environment, thus providing a certain degree of security.

  4. Cross-platform : wasmtimeCan run on a variety of operating systems and platforms, including Windows, Linux, and macOS.

  5. Efficient : wasmtimeAdvanced just-in-time compilation (JIT) technology is used to ensure that WebAssembly code can be executed efficiently.

In short, wasmtimeit is a runtime closely related to WebAssembly, which allows developers to execute WASM code in a non-browser environment, and provides support for WASI, thereby extending the capabilities and application scope of WebAssembly.

Preparation

environment

Please install it first wasiand https://github.com/bytecodealliance/wasmtime/releasesfind the suitable operating system to download wsmi

After the installation is complete, cmdexecute it to check whether the installation is successful

wasmtime

The effect is as shown in the figure.

Create a console project

Create a ConsoleApp2console project for

Add NuGet packages.

<ItemGroup>
      <PackageReference Include="Wasi.Sdk" Version="0.1.4-preview.10020" />
</ItemGroup>

Wasi.SdkIt is the sdk used to generate .wasmfiles, warehouse address: https://github.com/dotnet/dotnet-wasi-sdk

When we right-click the appropriate project and click Generate, bin/Debug|Releasea file will be generated under the folder of the current project {项目名称}.wasm, including .dllfiles of course.

generate .wasmfile

Select our project, right click 重新生成.

Then right click on the project and open the folder in the file explorer.

Open in sequence bin=> Release|Debug=>net7.0(看选择的SDK)

Open at the current path 控制台. Then wasmtimexecute the wasm file using.

wasmtime ConsoleApp2.wasm

This completes the simple wasm usage. Use c# to compile into wasm format, and then execute it.

implementwat

what iswat

WAT (WebAssembly Text Format) is a textual representation of WebAssembly. When we talk about WebAssembly (WASM), we usually mean its binary format, which is a low-level virtual machine code designed for browsers and other hosting environments. However, for the convenience of humans to read and write, WASM also has an equivalent text format, WAT.

Here are some key points about WAT:

  1. Readability : While the WASM binary format is designed for machines, the WAT format is designed for humans. It provides a more readable and editable way to represent WebAssembly code.

  2. Structure : WAT code typically consists of a series of directives, function definitions, and other module-level declarations. Its syntax is S-expression, a simple text format used to represent nested structures.

  3. Conversion : You can use tools such as wasm2watand wat2wasm, to convert between WAT and WASM. This means that you can manually write or modify WAT code and then compile it to WASM binary format, or decompile from existing WASM code to WAT format.

  4. Example : Here is a simple WAT example that defines a function that takes two integer arguments and returns their sum:

    (module
      (func $add (param $a i32) (param $b i32) (result i32)
        get_local $a
        get_local $b
        i32.add)
      (export "add" (func $add))
    )
    

In general, WAT is a textual representation of WebAssembly, which provides developers with a more intuitive and readable way to view, write or modify WebAssembly code.

Create a project in the current solution

Create a ConsoleApp1console project for

Add the nuget package to the project

  <ItemGroup>
    <PackageReference Include="wasmtime" Version="11.0.1" />
  </ItemGroup>

Official repository: https://github.com/bytecodealliance/wasmtime-dotnet

Then add a new test.watfile and write the code, the following code is WATthe code.

(module
  (import "" "table" (table $t 4 funcref))
  (func (export "call_indirect") (param i32 i32 i32) (result i32)
    (call_indirect $t (param i32 i32) (result i32) (local.get 1) (local.get 2) (local.get 0))
  )
)

Set test.watfile properties

Open Program.csthe file and modify the code

using Wasmtime;

using var engine = new Engine();
using var module = Module.FromTextFile(engine, "test.wat");
using var linker = new Linker(engine);
using var store = new Store(engine);

var table = new Table(store, TableKind.FuncRef, null, 4);

table.SetElement(0, Function.FromCallback(store, (int a, int b) => a + b));
table.SetElement(1, Function.FromCallback(store, (int a, int b) => a - b));
table.SetElement(2, Function.FromCallback(store, (int a, int b) => a * b));
table.SetElement(3, Function.FromCallback(store, (int a, int b) => a / b));

linker.Define("", "table", table);

var instance = linker.Instantiate(store, module);

var call_indirect = instance.GetFunction<int, int, int, int>("call_indirect");
if (call_indirect is null)
{
    Console.WriteLine("error: `call_indirect` export is missing");
    return;
}

Console.WriteLine($"100 + 25 = {call_indirect(0, 100, 25)}");
Console.WriteLine($"100 - 25 = {call_indirect(1, 100, 25)}");
Console.WriteLine($"100 * 25 = {call_indirect(2, 100, 25)}");
Console.WriteLine($"100 / 25 = {call_indirect(3, 100, 25)}");

Here is a test.watcase of calling using c#.

execute project

How to implement wasm in other languages?

Rust Compilation WebAssembly Guide - Zhihu (zhihu.com)

You can refer to this blog, use to compile rust into wasm, and then compile into wat format.

Technology Exchange

Qq technology exchange group: 737776595

For more technology sharing, pay attention to token的技术分享the official account

img

Guess you like

Origin blog.csdn.net/xiaohucxy/article/details/132157967