c#如何使用WASM跨语言调用?

简介: c#如何使用WASM跨语言调用?

介绍Wasm(WebAssembly)

WebAssembly(简称Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm被设计为编程语言的可移植编译目标,支持在web上部署客户端和服务器应用程序。

什么是wasmtime (WebAssembly Time)?它和WASM(WebAssembly)是什么关系?

wasmtime 是一个独立的、轻量级的 WebAssembly (WASM) 运行时,它支持 WASI (WebAssembly System Interface)。wasmtime 由 Bytecode Alliance 开发,该联盟致力于创建新的软件基础设施,使得模块化、可组合、安全和高效的软件成为可能。

wasmtime 和 WASM (WebAssembly) 的关系如下:

  1. WebAssembly 运行时: wasmtime 是一个运行时,它允许你在本地环境中执行 WebAssembly 代码,而不需要浏览器。这意味着你可以使用 wasmtime 运行任何编译为 WASM 的代码,无论是从 C、Rust、Go 还是其他语言编译的。

  2. 支持 WASI: wasmtime 是 WASI 的一个主要实现,这意味着它可以运行那些使用 WASI 接口的 WebAssembly 程序,从而让这些程序可以访问文件、网络和其他系统资源。

  3. 安全性: 与 WebAssembly 一样,wasmtime 也提供了一个沙盒环境,确保 WASM 代码在受限制的环境中运行,从而提供了一定的安全性。

  4. 跨平台: wasmtime 可以在多种操作系统和平台上运行,包括 Windows、Linux 和 macOS。

  5. 高效: wasmtime 使用了先进的即时编译 (JIT) 技术,确保 WebAssembly 代码能够高效地执行。

总之,wasmtime 是一个与 WebAssembly 紧密相关的运行时,它允许开发者在非浏览器环境中执行 WASM 代码,并提供了对 WASI 的支持,从而扩展了 WebAssembly 的能力和应用范围。

准备工作

环境

请先安装wasihttps://github.com/bytecodealliance/wasmtime/releases中找到适合的操作系统下载wsmi

安装完成以后在cmd中执行即可查看是否安装成功

wasmtime

效果如图。

创建一个控制台项目

创建一个ConsoleApp2的控制台项目

添加NuGet包。

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

Wasi.Sdk是用于生成.wasm文件的sdk,仓库地址:https://github.com/dotnet/dotnet-wasi-sdk

当我们右键项目的适合点击生成则会在当前项目的bin/Debug|Release文件夹下面生成一个{项目名称}.wasm的文件,当然还包括了.dll文件。

生成.wasm文件

选中我们的项目,右键重新生成

然后右键项目,在文件资源管理器中打开文件夹。

依次打开bin=>Release|Debug=>net7.0(看选择的SDK)

在当前路径打开控制台。然后使用wasmtim执行wasm文件。

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-expression,这是一种用于表示嵌套结构的简单文本格式。

  3. 转换: 你可以使用工具,如 wasm2watwat2wasm,来在 WAT 和 WASM 之间进行转换。这意味着你可以手动编写或修改 WAT 代码,然后将其编译为 WASM 二进制格式,或者从现有的 WASM 代码反编译为 WAT 格式。

  4. 示例: 下面是一个简单的 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)}");

这里提供了一个使用c#调用test.wat的案例。

执行项目

如何执行其他语言的wasm?

Rust 编译 WebAssembly 指南 - 知乎 (zhihu.com)

可以参考这个博客,使用将rust编译成wasm,然后在编译成wat格式。

技术交流

qq技术交流群:737776595

目录
相关文章
|
算法 Python
Python算法——广度优先搜索
Python算法——广度优先搜索
878 0
|
机器学习/深度学习 传感器 编解码
一文详解视觉Transformer在CV中的现状、趋势和未来方向(分类/检测/分割/多传感器融合)(中)
本综述根据三个基本的CV任务和不同的数据流类型,全面调查了100多种不同的视觉Transformer,并提出了一种分类法,根据其动机、结构和应用场景来组织代表性方法。由于它们在训练设置和专用视觉任务上的差异,论文还评估并比较了不同配置下的所有现有视觉Transformer。此外,论文还揭示了一系列重要但尚未开发的方面,这些方面可能使此类视觉Transformer能够从众多架构中脱颖而出,例如,松散的高级语义嵌入,以弥合视觉Transformer与序列式之间的差距。最后,提出了未来有前景的研究方向。
一文详解视觉Transformer在CV中的现状、趋势和未来方向(分类/检测/分割/多传感器融合)(中)
|
8月前
|
机器学习/深度学习 算法 C++
【DFS/回溯算法】2016年蓝桥杯真题之路径之谜详解
题目要求根据城堡北墙和西墙箭靶上的箭数,推断骑士从西北角到东南角的唯一路径。每步移动时向正北和正西各射一箭,同一格不重复经过。通过DFS回溯模拟“拔箭”过程,验证路径合法性。已知箭数约束路径唯一,最终按编号输出行走顺序。
|
消息中间件 监控 NoSQL
利用RabbitMQ与Redis实现消息的延迟传递的策略
这个系统就如同一个无懈可击的邮局,无论天气如何变换,它都能确保每一封信准时送达。通过巧妙地运用RabbitMQ的DLX和Redis的Sorted Sets,我们搭建了一座桥梁,让即时和延迟消息的传递高效且无缝对接。
224 3
|
10月前
|
存储 安全 前端开发
如何开发一套EHS 健康安全环境管理系统?(附架构图+流程图+代码参考)
本文介绍如何开发一套完整的EHS(健康、安全和环境)管理系统,涵盖系统核心模块、技术架构、数据库设计、前后端开发示例及上线建议,帮助企业提升安全管理效率与合规性。
|
Ubuntu Linux Shell
Ubuntu gnome WhiteSur-gtk-theme类mac主题正确安装和卸载方式
通过这个过程,用户不仅可以定制自己的桌面外观,还可以学习到更多关于 Linux 系统管理的知识,从而更好地掌握系统配置和主题管理的技巧。
2626 12
|
机器学习/深度学习 人工智能 安全
Stable Diffusion 3.0 :一键开启你的AI绘画之旅
本文介绍了Stable Diffusion 3.0的主要优化,包括采用DiT架构提升多对象生成能力及“流匹配”技术加速采样。同时解决了部署复杂、显卡需求高等问题,可通过阿里云计算巢一键部署,实现即开即用。文章展示了人像、动漫风、科幻风等生成效果,并提供中文菜单设置与插件下载教程。无论是专业设计师还是普通用户,都能轻松开启智能创作新时代。 Flux模型支持即将上线,值得期待。
|
人工智能 自然语言处理
Claude
Claude 3是由人工智能初创公司Anthropic推出的一款大型语言模型,旨在更好地执行复杂的指令。Cla
1096 1
|
机器学习/深度学习 存储 自然语言处理
深度学习之模型剪枝
模型剪枝(Model Pruning)是深度学习中一种减少模型复杂度、提高计算效率的方法。通过删除冗余的神经元或连接,剪枝能够在不显著影响模型性能的前提下,减少模型参数数量、降低计算和存储需求。
1032 3

热门文章

最新文章