查看原文
其他

用Wasm连接Rust与Python | Rust 学习笔记(三)

The following article is from 李大狗Leeduckgo Author 李大狗就是我



本文是"Rust 学习笔记"系列的第三篇。其他两篇请见文末。


本篇是魔改出一个 Encoder | Rust 学习笔记(一)注1的进一步延伸,在那一篇中,我们借助 Yew 和 Trunk,对 Wasm 进行了"快速上手实践"。

代码见:
https://github.com/leeduckgo/Rust-Study/tree/main/b64-encoder

但是,在浏览器中运行只是 Wasm 的玩法之一:


WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C / C ++ 等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。


简而言之,对于网络平台而言,WebAssembly 具有巨大的意义——它提供了一条途径,以使得以各种语言编写的代码都可以以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件都将可以运行在 Web 中。


Wasm 还有另一种套玩法 —— 我们可以将 WASM 作为普通程序运行,也可以成为其他编程语言的模块,这也是本文所要讨论的。

作为普通程序/普通模块,Wasm 具有如下两点 AmAzING 的特性:


1.安全访问


你现在找到的大部分 WebAssembly 教程和例子都是聚焦在浏览器之中,比如如何加速网页或者网页应用各种各样的功能。无论如何,WebAssembly 真正强大的领域但是被提及的很少:浏览器之外的领域;也是我们接下来系列关注的点。


浏览器之外,它的主要优势就是可以用不用妥协安全的前提下提供系统级别的访问。它是通过 WASI 完成的;Web Assembly System Interface(WASI 全称,大致意思就是 WebAssembly 系统接口)是一个类 C 的函数集,在安全的方式提供功能性的系统访问,如 fd_readrandfd_write、线程(WIP) 等等。
这里举出一些你可能使用的场景(当然是非浏览器场景):

  • 视频游戏的脚本语言;

  • 最低负载运行代码,就像 Fastly/Cloudflare 的边缘计算(compute-at-edge)场景;

  • 最低运行负载在 IOT 设备安全地运行易于更新的代码;

  • 不需要 JIT 就能在你的环境中获取极快的性能;


https://n3xtchen.github.io/n3xtchen/rust/2020/08/17/webassembly-without-the-browser-part1


2.让不同的编程语言程序之间更自由的调用


作为一种"低级语言",Wasm程序可以很好的成为不同编程语言程序之间沟通的桥梁,同时避免了在一台服务器上安装多种语言的环境。
例如,我们可以在 Python 中调用用Wasm程序写的模块:
https://github.com/bytecodealliance/wasmtime-py
现在,让我们开始实践之旅吧!
注:本文对如下内容有所参考——
https://zhuanlan.zhihu.com/p/352196567

1 创建 Rust Lib 程序

在之前的文章中,我们通过如下命令创建一个 Rust 项目。
cargo new foobar
然而,有的时候,我们希望创建一个库,以供其他程序进行调用,如本节课我们要生成与调用的wasm程序,即是一个库。
我们通过加上--lib 参数以生成一个库项目。
cargo new --lib adder
实际上,你去探索上述命令行生成的文件,发现它们的 Cargo.toml 完全一样,区别仅在于 src 目录下,可执行工程是一个 main.rs,而库工程是一个 lib.rs。

2 完善 Rust Lib 程序

用如下代码替换lib.rs的内容:
#[no_mangle]pub extern "C" fn adder(a: i32, b: i32) -> i32 { a + b}
这段代码中的关键是#[no_mangle]
#[no_mangle]告诉Rust编译器不要修改函数名称,这样我们才能在其他程序中通过函数名调用生成的Wasm,不写会生成 _ZN4rustfn1_34544tert54grt5 类似的混淆名。
Cargo.toml文件中,我们添加如下代码:
[lib]crate-type = ['cdylib']
这两行代码表示我们编译时将会生成系统库,以供其他编程语言的程序调用。

3 编译为 Wasm 模块

执行如下命令:
cargo build --release --target wasm32-wasi
执行成功后,我们将在target/wasm32-wasi/release目录下看到adder.wasm文件。

4 通过 Python 调用 Wasm

这里我们选择这个Python库:
https://github.com/wasmerio/wasmer-python
安装库:
pip3 install wasmer==1.0.0pip3 install wasmer_compiler_cranelift==1.0.0
调用:
确保我们在target/wasm32-wasi/release目录下。
打开python或者ipython
输入:
from wasmer import engine, Store, Module, Instancefrom wasmer_compiler_cranelift import Compiler
# Let's define the store, that holds the engine, that holds the compiler.store = Store(engine.JIT(Compiler))
# Let's compile the module to be able to execute it!module = Module(store, open('adder.wasm', 'rb').read())
# Now the module is compiled, we can instantiate it.instance = Instance(module)
# Call the exported `sum` function.result = instance.exports.adder(5, 37)
print(result) # 42!

5 示例代码

本系列所有源码在如下Repo 中开源:
https://github.com/leeduckgo/Rust-Study
在该目录下,用本教程方法编译,安装必要的 Python 包,然后执行:
python3 run_adder.py
即可看到效果。

点击链接查看本系列代码:https://github.com/leeduckgo/Rust-Study

About Patract


Patract 为波卡 Wasm 合约生态的平行链和 DApp 开发提供解决方案。我们帮助社区平行链设计和开发链上合约模块和 Runtime 支持,并且为 DApp 开发者提供覆盖开发、测试、调试、部署、监控、数据提供和前端开发等阶段的全栈工具和服务支持。

How to join Patract


1.对于合约开发者,可以访问官网 (https://patract.io),熟悉测试链和工具套件。欢迎加入官方开发群:
Element(https://app.element.io/#/room/#PatractLabsDev:matrix.org)
Discord(https://discord.gg/wJ8TnTfjcq)
 
2.对于将要集成 Wasm 合约功能的平行链项目方,或者使用 Wasm 合约开发的 DApp 项目方,商务合作欢迎联系 santry@patract.io
 
3.对于用户,欢迎加入:
Telegram(https://t.me/patract)
Twitter(https://twitter.com/PatractLabs)
 
4.对于求职者,我们在招聘区块链开发工程师、前端/全栈开发工程师、产品经理、开发者运营等岗位,可以联系 sean@patract.io

扫码加入Patract 微信开发群



往期精彩:
//Mapping 数据结构 | 用 Rust 写智能合约(二)
//Hello, ink! | Substrate 智能合约极速入门(一)

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存