您好,登录后才能下订单哦!
这篇文章将为大家详细讲解有关Go如何实现Plugins插件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
golang 1.8 及以上版本提供了一个创建共享库(shared object)的新工具,称为 Plugins。目前 Plugins 仅在 Linux、FreeBSD 和 macOS 上受支持,且只支持 golang 调用。
使用示例,定义一个 plugin.go
:
package main import ( "log" ) func init() { log.Println("plugin init") } type SayHello struct { } func (s *SayHello) CallMe(name string) string { log.Println("hello ", name) return "I am plugin" } // SayHelloPlugin 导出变量 var SayHelloPlugin SayHello
使用 -buildmode=plugin
模式编译出 plugin.so
共享库
go build -o plugin.so -buildmode=plugin plugin.go
main.go
中调用插件:
package main import ( "log" "plugin" ) type CustomPlugin interface { CallMe(name string) string } func main() { // 打开插件(并发安全) p, err := plugin.Open("plugin.so") if err != nil { panic(err) } // 在插件中搜索可导出的变量或函数 sayHelloPlugin, err := p.Lookup("SayHelloPlugin") if err != nil { panic(err) } // 断言插件类型 if sayHello, ok := sayHelloPlugin.(CustomPlugin); ok { log.Println(sayHello.CallMe("togettoyou")) } }
go run main.go # 输出 2021/07/28 17:07:21 plugin init 2021/07/28 17:07:21 hello togettoyou 2021/07/28 17:07:21 I am plugin
定义一个插件总结:
package 包名需要定义为 main
必须有可导出的变量或函数
不需要 main 函数
插件加载时会先执行 init 函数
Yaegi 是 Traefik 开源的 Go 解释器。Traefik 自身的插件实现就是使用的 Yaegi 。
Yaegi 运行在 Go 运行时之上,可以直接作为嵌入式解释器,或使用交互式 shell ,解释运行 Go 代码。不过只支持 Go 1.15 和 Go 1.16(最新的 2 个主要版本)。
创建代码目录结构如下:
│ go.mod │ go.sum │ main.go │ └─plugin └─src └─hello go.mod hello.go
这里有个注意点,Yaegi 的插件需要放在 src 目录下。
其中 hello.go
代码:
package hello import ( "fmt" ) func init() { fmt.Println("hello plugin init") } func CallMe(msg string) string { fmt.Println(msg) return "I am plugin" }
main.go
代码:
package main import ( "fmt" "github.com/traefik/yaegi/interp" "github.com/traefik/yaegi/stdlib" ) func main() { // 初始化解释器 i := interp.New(interp.Options{GoPath: "./plugin/"}) // 插件需要使用标准库 if err := i.Use(stdlib.Symbols); err != nil { panic(err) } // 导入 hello 包 if _, err := i.Eval(`import "hello"`); err != nil { panic(err) } // 调用 hello.CallMe v, err := i.Eval("hello.CallMe") if err != nil { panic(err) } callMe := v.Interface().(func(string) string) fmt.Println(callMe("togettoyou")) }
go run main.go # 输出 hello plugin init togettoyou I am plugin
关于“Go如何实现Plugins插件”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。