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中切片copy复制和等号复制的区别介绍
Apr 27 Golang
golang goroutine顺序输出方式
Apr 29 Golang
Go使用协程交替打印字符
Apr 29 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 Golang
golang用type-switch判断interface的实际存储类型
Apr 14 Golang
Golang 链表的学习和使用
Apr 19 Golang
实现GO语言对数组切片去重
Apr 20 Golang
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
Jun 21 Golang
Go语言怎么使用变长参数函数
Jul 15 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
ThinkPHP连接数据库的方式汇总
2014/12/05 PHP
Eclipse PHPEclipse 配置的具体步骤
2017/08/08 PHP
Javascript模块化编程(一)模块的写法最佳实践
2013/01/17 Javascript
详解jQuery插件开发中的extend方法
2013/11/19 Javascript
js控制分页打印、打印分页示例
2014/02/08 Javascript
JavaScript插件化开发教程 (三)
2015/01/27 Javascript
JavaScript中原型和原型链详解
2015/02/11 Javascript
jquery实现的淡入淡出下拉菜单效果
2015/08/25 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
Ionic如何创建APP项目
2016/06/03 Javascript
JS采用绝对定位实现回到顶部效果完整实例
2016/06/20 Javascript
浅谈js对象属性 通过点(.) 和方括号([]) 的不同之处
2016/10/29 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
javascript 中select框触发事件过程的分析
2017/08/01 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
javaScript中"=="和"==="的区别详解
2018/03/16 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
2019/09/24 Javascript
js实现点击选项置顶动画效果
2020/08/25 Javascript
JS如何操作DOM基于表格动态展示数据
2020/10/15 Javascript
python 中的列表解析和生成表达式
2011/03/10 Python
Python生成pdf文件的方法
2014/08/04 Python
搭建Python的Django框架环境并建立和运行第一个App的教程
2016/07/02 Python
Python 正则表达式实现计算器功能
2017/04/29 Python
Python何时应该使用Lambda函数
2019/07/02 Python
Python Web程序搭建简单的Web服务器
2019/07/31 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
Python中实现输入一个整数的案例
2020/05/03 Python
django 实现后台从富文本提取纯文本
2020/07/02 Python
高中自我鉴定范文
2013/11/03 职场文书
会计与审计专业自荐信范文
2014/03/15 职场文书
大学中国梦演讲稿
2014/04/23 职场文书
史学专业毕业生求职信
2014/05/09 职场文书
师德师风剖析材料
2014/09/30 职场文书
企业党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
围城读书笔记
2015/06/26 职场文书
草系十大最强宝可梦,纸片人上榜,榜首大家最熟悉
2022/03/18 日漫