Go WASM 导出函数

huangapple go评论109阅读模式
英文:

Go WASM export functions

问题

我想创建一个.wasm文件,在编译时仍然导出函数名。

package main

import (
	"fmt"
)

func main() {
	fmt.Println("Main")
}

func MyFunc() {
	fmt.Println("MyFunc")
}

我使用以下命令进行构建

GOOS=js GOARCH=wasm go build -o main.wasm

这将生成wasm文件(很棒,Go原生支持wasm)。

但是使用wabt并进行对象转储会暴露这些函数。

Export[4]:
 - func[958] <wasm_export_run> -> "run"
 - func[959] <wasm_export_resume> -> "resume"
 - func[961] <wasm_export_getsp> -> "getsp"
 - memory[0] -> "mem"

我期望看到类似于

func[137] <MyFunc> -> "MyFunc"

有人知道如何在Go WASM中导出函数吗?

在Rust中,包括#[no_mangle]pub extern "C"可以使函数在wasm-pack的输出中保持可用。我正在寻找类似于Go的方法。

英文:

I want to create a .wasm file which still has the function names exported when compiled.

package main

import (
	&quot;fmt&quot;
)

func main() {
	fmt.Println(&quot;Main&quot;)
}

func MyFunc() {
	fmt.Println(&quot;MyFunc&quot;)
}

I'm building with

GOOS=js GOARCH=wasm go build -o main.wasm

Which produces the wasm file (and awesome that Go targets wasm natively).

But using wabt and doing an object dump exposes these functions.

Export[4]:
 - func[958] &lt;wasm_export_run&gt; -&gt; &quot;run&quot;
 - func[959] &lt;wasm_export_resume&gt; -&gt; &quot;resume&quot;
 - func[961] &lt;wasm_export_getsp&gt; -&gt; &quot;getsp&quot;
 - memory[0] -&gt; &quot;mem&quot;

I'm expecting to see something like

func[137] &lt;MyFunc&gt; -&gt; &quot;MyFunc&quot;

Does anyone know how to export functions in Go WASM?

In rust including #[no_mangle] and pub extern &quot;C&quot; keeps the function available in the output with wasm-pack. I'm looking for something similar with Go.

答案1

得分: 7

如果你计划在Go中编写大量的WASM代码,你可能想考虑使用TinyGo进行编译,它是一个用于嵌入式和WASM的Go编译器。

TinyGo支持//export <name>或别名//go:export <name>的注释指令,可以实现你所需的功能。

我将复制粘贴TinyGo WASM文档中的第一个示例:

package main

// This calls a JS function from Go.
func main() {
    println("adding two numbers:", add(2, 3)) // expecting 5
}

// ...omitted

// This function is exported to JavaScript, so can be called using
// exports.multiply() in JavaScript.
//export multiply
func multiply(x, y int) int {
    return x * y;
}

你可以使用以下命令构建它:tinygo build -o wasm.wasm -target wasm ./main.go


标准的Go编译器正在进行一个持续的开放讨论,讨论如何复制TinyGo的功能。简而言之,你可以通过将函数设置为JS全局命名空间来实现,使用js.Global().Set(...)

英文:

If you plan to write a lot of WASM in Go, you might want to consider compiling with TinyGo, which is a Go compiler for embedded and WASM.

TinyGo supports a //export &lt;name&gt; or alias //go:export &lt;name&gt; comment directive that does what you're looking for.

I'm copy-pasting the very first example from TinyGo WASM docs:

package main

// This calls a JS function from Go.
func main() {
    println(&quot;adding two numbers:&quot;, add(2, 3)) // expecting 5
}

// ...omitted

// This function is exported to JavaScript, so can be called using
// exports.multiply() in JavaScript.
//export multiply
func multiply(x, y int) int {
    return x * y;
}

And you build it with: tinygo build -o wasm.wasm -target wasm ./main.go.

<hr>

The standard Go compiler has an ongoing open discussion about replicating TinyGo feature. The tl;dr seems to be that you can achieve this by setting funcs to the JS global namespace, with the js.Global().Set(...)

huangapple
  • 本文由 发表于 2021年6月15日 08:03:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/67978442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定