18910140161

利用Golang玩转WebAssembly

顺晟科技

2021-06-16 11:00:49

673

网络组装(WebAssembly),又称为WAMS,是一种新的二进制格式,具有可移植性、体积小、加载速度快、与网络兼容等特点。它可以将C/C /Rust等语言编写的代码编译成wasm文件,并在Web上运行。

用C/C写wasm有点麻烦,需要安装各种编译器。说最新的Go 1.11已经发布,新特性之一就是对WebAssembly的支持。今天我们将播放如何将Go代码编译成wasm文件。

提示:本文不会介绍围棋的相关语法和WASM的相关基础知识。如果阅读有困难,请参考相关基础介绍或先阅读相关文章。

环境设备

环境安装就不多说了,直接参考官方的安装文档,然后配置相应的环境变量即可。例如,在windows上,运行以下命令“确定”意味着一切正常:

C: \用户\管理员版本

go版本go1.11 windows/amd64

给我一个样本

首先,用以下内容创建一个main.go文件:

包装总管

func main() {

println('你好,WebAssembly!')

}

代码很简单,就是程序运行后直接输出Hello,WebAssembly!

然后进入控制台(您需要在windows上首先输入git bash)并输入以下命令:

go arch=wasm GOOS=js go build-o test . wasm main . go

这句话的意思是把Go的编译架构切换到wasm,运行对象是Javascript引擎,然后源代码是main.go,最后输出的是二进制文件test.wasm

生成的test.wasm需要加载到浏览器中才能使用。为了方便起见,Go提供了默认的加载示例和脚本。您可以复制脚本和示例:

CP $(go env GOROOT)/misc/wasm/wasm _ exec。{html,js}。

以上是指将Go安装目录中的wasm_exec.html和wasm_exec.js复制到当前文件夹。一切就绪后,我们用http-server(可以通过npm安装http-server安装)启动一个Web服务器:

http-server -c 0 -p 2000

转到http://localhost 33602000/wasm _ exec.html打开控制台,您将看到以下内容:

你好,WebAssembly!

深入的例子

直接显示Hello world这样的提示不好玩。可以调用Go中的方法吗?答案是肯定的。我们首先修改wasm_exec.html,并将其更改为以下内容:

!声明文档类型

超文本标记语言

meta charset='utf-8 '

titleGo wasm/title

/head

身体

脚本src=' wasm _ exec . js '/脚本

脚本

if(!web assembly . instancestreamming){//poly ill

web assembly . instantestreaming=async(resp,importObject)={

const source=await(等待响应)。arrayBuffer()

实例化(源,导入对象)

}

}

const go=新go()

让mod,inst

web ASSEMbLY . InstanceStreaming(fetch(' test . wasm '),go.importObject)。然后(异步结果={

mod=result.module

inst=结果. instance

等待go.run(inst)

})

函数wamsCallback(值){

console . log(` wasm output : $ { value } `)

}

/script

pHello/p

输入id='name' /

/body

/html

接下来,修改main.go并添加以下代码:

包装总管

导入(

“syscall/js”

)

func calFib(n int) int {

a :=0

b :=1

对于I :=0;I n;i {

a,b=b,a b

}

退货b

}

func fib(params []js。值){

值:=params[0]。Int()

值=calFib(值)

//目前Go与wasm交互,wasm无法直接得到函数的返回值。调用window.wamsCallback(value)或直接从window.output获取

//window.wamsCallback是Javascript中用户自定义的函数,也就是回调函数

js。全局()。设置(“输出”,值)

js。全局()。调用(' wamsCallback ',值)

}

//将方法注入窗口

func registerCallbacks() {

js。全局()。Set('fibNative ',js。新回调(fib))

}

func main() {

registerCallbacks()

选择{}

}

在上面的代码中,我们在Go中添加了一个计算斐波那契序列的方法,并通过Go中的registerCallbacks注入到浏览器中。Js。Global()表示获取宿主环境的窗口(浏览器)或全局(Node.js)。调用意味着调用相应的方法。因此,在wasm被成功加载到浏览器中之后,我们可以通过函数窗口访问Go中的fib方法.

去现在对世界睡眠医学协会的支持属于试验阶段,相关应用程序接口还不完善,我们现在还没法直接获得返回值。在代码中,我们可以将返回值通过js .全局()。设置("输出",值)将计算的返回值直接写到窗户。输出里面,或者调用我们页面中已有的函数。

在chrome _ 6494 _ 1。html ' target=' _ blank ' Chrome控制台,我们可以得到这样的结果:

你好,WebAssembly!

window.fibNative(3)

wasm _ exec。html :28 wasm输出: 3

窗户。输出

3

window.fibNative(30)

wasm_exec.html:28 wasm输出: 1346269

窗户。输出

1346269

在去中,通过syscall/js这个官方提供的开发库还是可以调用页面中的数字正射影像图并操作,例如:

包装总管

导入(

" syscall/js "

)

func changeBodyColor(color []js .值){

//文档。尸体。风格。颜色=颜色

js .全局()。获取('文档')。获取(正文).Set('style ',' color:' color[0]).String())

}

func setInputValue(val []js .值){

id :=val[0].字符串()

//document.getElementById(id).值='从开始的值'

js .全局()。获取('文档')。调用(' getElementById ',Id).设置('值','开始时的值)

}

//将去里面的方法注入到window.fibNative里面

func registerCallbacks() {

js .全局()。Set('changeBodyColor ',js .新回调(更改主体颜色))

js .全局()。Set('setInputValue ',js .新回调(设置输入值))

}

func main() {

registerCallbacks()

选择{}

}

重新编译为世界睡眠医学协会后,可以通过window.changeBodyColor('红色)和设置输入值('名称)来切换页面颜色以及给文本框一个默认值。

再来一个计算数组和的样例:

包装总管

导入(

" syscall/js "

)

func sum(params []js .值){

结果:=0

对于_,值:=范围参数{

结果=值Int()

}

js .全局()。调用(' wamsCallback ',结果)

}

func registerCallbacks() {

js .全局()。Set('sumNative ',js .新回调(总和))

}

func main() {

println('你好,WebAssembly!')

registerCallbacks()

选择{}

}

这样,我们可以通过window.sumNative(1,2,3)来调用去的计算和的方法

总结

以上是在去中使用世界睡眠医学协会的基本方法。当前去对世界睡眠医学协会的支持还属于实验阶段,官方也提到现在提供的应用程序接口也不多,重要用于测试和验证。还有就是,当前的世界睡眠医学协会二进制文件大小大约为1.2Mb左右,比于C生成的世界睡眠医学协会要大不少,主要是里面包含的去的一些运行时,所以会大点。以后也许会优化。

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航