C# は WASM を使用して言語間でどのように呼び出しますか?

Wasm (WebAssembly) の紹介

WebAssembly (略して Wasm) は、スタックベースの仮想マシン用のバイナリ命令形式です。Wasm は、Web 上でのクライアントおよびサーバー アプリケーションの展開をサポートするプログラミング言語の移植可能なコンパイル ターゲットとして設計されています。

wasmtime (WebAssembly Time) とは何ですか? WASM (WebAssembly) との関係は何ですか?

wasmtimeは、WASI (WebAssembly System Interface) をサポートするスタンドアロンの軽量 WebAssembly (WASM) ランタイムです。wasmtimeBytecode Alliance によって開発されました。Bytecode Alliance は、モジュール式で構成可能、安全かつ効率的なソフトウェアを可能にする新しいソフトウェア インフラストラクチャの作成に特化したアライアンスです。

wasmtimeWASM(WebAssembly)との関係は以下の通りです。

  1. WebAssembly ランタイム:wasmtimeブラウザーを必要とせずにローカル環境で WebAssembly コードを実行できるようにするランタイムです。wasmtimeこれは、C、Rust、Go、または別の言語からコンパイルされたかどうかにかかわらず、WASM にコンパイルされたコードを を使用して実行できることを意味します。

  2. WASI サポート: wasmtimeWASI の主要な実装です。つまり、WASI インターフェイスを使用する WebAssembly プログラムを実行でき、これらのプログラムがファイル、ネットワーク、およびその他のシステム リソースにアクセスできるようになります。

  3. セキュリティ: WebAssembly と同様に、wasmtimeWASM コードが制限された環境で実行されることを保証するサンドボックス環境も提供し、ある程度のセキュリティを提供します。

  4. クロスプラットフォーム: wasmtimeWindows、Linux、macOS など、さまざまなオペレーティング システムとプラットフォームで実行できます。

  5. 効率的:wasmtime高度なジャストインタイム コンパイル (JIT) テクノロジを使用して、WebAssembly コードを効率的に実行できます。

つまり、wasmtimeこれは WebAssembly と密接に関連したランタイムであり、開発者が非ブラウザ環境で WASM コードを実行できるようにし、WASI のサポートを提供することで、WebAssembly の機能とアプリケーション範囲を拡張します。

準備

環境

まずインストールしてwasihttps://github.com/bytecodealliance/wasmtime/releaseswsmi をダウンロードするのに適したオペレーティング システムを見つけてください。

インストールが完了したら、cmdそれを実行してインストールが成功したかどうかを確認します

wasmtime

効果は図の通りです。

コンソールプロジェクトを作成する

ConsoleApp2コンソールプロジェクトを作成します

NuGet パッケージを追加します。

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

Wasi.Sdkファイルの生成に使用される SDK です.wasm。ウェアハウスのアドレス: https://github.com/dotnet/dotnet-wasi-sdk

適切なプロジェクトを右クリックして「生成」をクリックすると、現在のプロジェクトのbin/Debug|Releaseフォルダーの下にファイルが生成されます{项目名称}.wasm(.dllもちろんファイルも含まれます)。

.wasmファイルを生成する

プロジェクトを選択し、右クリックします重新生成

次に、プロジェクトを右クリックし、ファイル エクスプローラーでフォルダーを開きます。

順に開くbin=> Release|Debug=>net7.0(看选择的SDK)

現在のパスで開きます控制台次に、wasmtimwasm ファイルを使用して実行します。

wasmtime ConsoleApp2.wasm

これで簡単な wasm の使い方が完了しました。c#を使用してwasm形式にコンパイルし、実行します。

埋め込むwat

とはwat

WAT (WebAssembly Text Format) は、WebAssembly のテキスト表現です。WebAssembly (WASM) について話すときは、通常、そのバイナリ形式を指します。これは、ブラウザやその他のホスティング環境用に設計された低レベルの仮想マシン コードです。ただし、人間が読み書きしやすいように、WASM には同等のテキスト形式である WAT も用意されています。

WAT に関する重要なポイントは次のとおりです。

  1. 可読性: WASM バイナリ形式はマシン用に設計されていますが、WAT 形式は人間用に設計されています。これにより、WebAssembly コードを表現するための、より読みやすく編集しやすい方法が提供されます。

  2. 構造: WAT コードは通常、一連のディレクティブ、関数定義、およびその他のモジュール レベルの宣言で構成されます。その構文は S 式です。これは、ネストされた構造を表すために使用される単純なテキスト形式です。

  3. 変換wasm2wat:や などのツールを使用してwat2wasm、WAT と WASM の間で変換できます。これは、WAT コードを手動で作成または変更してから、それを WASM バイナリ形式にコンパイルしたり、既存の WASM コードから WAT 形式に逆コンパイルしたりできることを意味します。

  4. : これは、2 つの整数引数を受け取り、その合計を返す関数を定義する簡単な WAT の例です。

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

一般に、WAT は WebAssembly のテキスト表現であり、WebAssembly コードを表示、作成、変更するためのより直観的で読みやすい方法を開発者に提供します。

現在のソリューションでプロジェクトを作成する

ConsoleApp1コンソールプロジェクトを作成します

nuget パッケージをプロジェクトに追加する

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

公式リポジトリ: https://github.com/bytecodealliance/wasmtime-dotnet

次に、新しいtest.watファイルを追加してコードを記述します。次のコードがWATそのコードです。

(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))
  )
)

test.watファイルのプロパティを設定する

ファイルを開いてProgram.csコードを変更します

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)}");

ここではtest.watC#を使って呼び出した例を紹介します。

プロジェクトを実行する

他の言語で wasm を実装するにはどうすればよいですか?

Rust コンパイル WebAssembly ガイド - Zhihu (zhihu.com)

このブログを参照して、rust を wasm にコンパイルし、wat 形式にコンパイルすることができます。

技術交流

Qq技術交流グループ:737776595

さらに技術を共有したい場合は、token的技术分享公式アカウントに注目してください

画像

おすすめ

転載: blog.csdn.net/xiaohucxy/article/details/132157967