Go Plugins插件的实现方式
作者:togettoyou 时间:2023-10-15 01:51:20
官方实现
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 函数
Traefik Yaegi 实现
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
来源:https://www.cnblogs.com/togettoyou/p/goplugins.html
标签:Go,Plugins,插件


猜你喜欢
配置mysql允许远程连接的方法
2024-01-24 00:31:56
Python3实现捕获Ctrl+C终止信号
2021-10-17 14:03:55
MySQL优化之InnoDB优化
2024-01-14 07:06:20
python 控制Asterisk AMI接口外呼电话的例子
2021-07-01 16:59:39
浅析Python 实现一个自动化翻译和替换的工具
2021-12-03 20:48:25

JavaScript字符串对象toLowerCase方法入门实例(用于把字母转换为小写)
2024-05-08 10:10:47
Python lambda表达式原理及用法解析
2021-03-02 18:52:12
vue车牌搜索组件使用方法详解
2024-04-30 10:30:37

python之pkl文件的用法及说明
2021-02-21 21:44:57

python写入文件如何取消自动换行
2023-11-28 22:39:11
浅谈sql连接查询的区别 inner,left,right,full
2024-01-17 08:23:35
php flv视频时间获取函数
2023-09-04 13:41:48
Dreamweaver给你的网页盖个章
2008-02-03 11:35:00
Python 字符串的有关知识详解
2022-03-14 16:54:12
javascript实现延时显示提示框特效代码
2024-04-25 13:10:50
Python垃圾回收机制三种实现方法
2023-02-22 00:24:42

python-xpath获取html文档的部分内容
2022-10-06 19:41:52

python yield关键词案例测试
2021-02-07 03:14:07
详解python读写json文件
2022-11-01 16:18:53
SQL Join的一些总结(实例)
2012-08-21 10:19:29