Go Plugins插件的实现方式


Posted in Golang onAugust 07, 2021

官方实现

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

到此这篇关于Go Plugins插件的实现方式的文章就介绍到这了,更多相关Go Plugins插件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Golang 相关文章推荐
Golang 正则匹配效率详解
Apr 25 Golang
golang中切片copy复制和等号复制的区别介绍
Apr 27 Golang
go 原生http web 服务跨域restful api的写法介绍
Apr 27 Golang
goland 恢复已更改文件的操作
Apr 28 Golang
Go语言基础知识点介绍
Jul 04 Golang
golang内置函数len的小技巧
Jul 25 Golang
Go语言特点及基本数据类型使用详解
Mar 21 Golang
golang实现浏览器导出excel文件功能
Mar 25 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Apr 10 Golang
Golang 对es的操作实例
Apr 20 Golang
Golang日志包的使用
Apr 20 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 #Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 #Golang
手把手教你导入Go语言第三方库
Aug 04 #Golang
Go语言实现Base64、Base58编码与解码
Jul 26 #Golang
golang内置函数len的小技巧
Jul 25 #Golang
修改并编译golang源码的操作步骤
Go语言应该什么情况使用指针
Jul 25 #Golang
You might like
Email+URL的判断和自动转换函数
2006/10/09 PHP
php 无限级数据JSON格式及JS解析
2010/07/17 PHP
解决CodeIgniter伪静态失效
2014/06/09 PHP
php遍历CSV类实例
2015/04/14 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
php版微信自定义回复功能示例
2016/12/05 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
JS date对象的减法处理实现代码
2010/12/28 Javascript
javascript操纵OGNL标签示例代码
2014/06/16 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
javascript转换静态图片,增加粒子动画效果
2015/05/28 Javascript
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
对vue2.0中.vue文件页面跳转之.$router.push的用法详解
2018/08/24 Javascript
javascript实现评分功能
2020/06/24 Javascript
在Vue 中实现循环渲染多个相同echarts图表
2020/07/20 Javascript
Python实现读写sqlite3数据库并将统计数据写入Excel的方法示例
2017/08/07 Python
python GUI实例学习
2017/11/21 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
python3 实现调用串口功能
2019/12/26 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
美国领先的奢侈美容零售商:Bluemercury
2017/07/26 全球购物
C面试题
2015/10/08 面试题
新员工培训个人的自我评价
2013/10/09 职场文书
人力资源行政经理自我评价
2013/10/23 职场文书
物业管理个人自我评价
2013/11/08 职场文书
求职信写作要突出重点
2014/01/01 职场文书
2014年端午节活动方案
2014/03/11 职场文书
基层党支部公开承诺书
2014/05/29 职场文书
企业环保标语
2014/06/10 职场文书
2013年最新自荐信范文
2014/06/23 职场文书
三月雷锋月活动总结
2014/07/03 职场文书
先进个人申报材料
2014/12/30 职场文书
小学教师自我评价
2015/03/04 职场文书
教你用eclipse连接mysql数据库
2021/04/22 MySQL