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 相关文章推荐
Go语言操作数据库及其常规操作的示例代码
Apr 21 Golang
go语言-在mac下brew升级golang
Apr 25 Golang
Go语言切片前或中间插入项与内置copy()函数详解
Apr 27 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 Golang
解决go在函数退出后子协程的退出问题
Apr 30 Golang
解决Golang中goroutine执行速度的问题
May 02 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
golang内置函数len的小技巧
Jul 25 Golang
Go中的条件语句Switch示例详解
Aug 23 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
Go获取两个时区的时间差
Apr 20 Golang
深入理解 Golang 的字符串
May 04 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
PHP 数组和字符串互相转换实现方法
2013/03/26 PHP
如何使用php输出时间格式
2013/08/31 PHP
PHP中filter函数校验数据的方法详解
2015/07/31 PHP
PHP文件上传类实例详解
2016/04/08 PHP
Yii2增加验证码步骤详解
2016/04/25 PHP
Joomla调用系统自带编辑器的实现方法
2016/05/05 PHP
PHP实现一个多功能购物网站的案例
2017/09/13 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
DOM精简教程
2006/10/03 Javascript
jquery之Document元素选择器篇
2008/08/14 Javascript
JavaScript 构造函数 面相对象学习必备知识
2010/06/09 Javascript
jQuery实现的多选框多级联动插件
2014/05/02 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
AngularJS入门教程之双向绑定详解
2016/08/18 Javascript
jQuery中的select操作详解
2016/11/29 Javascript
jstree单选功能的实现方法
2017/06/07 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
js实现导航跟随效果
2018/11/17 Javascript
vue 设置 input 为不可以编辑的实现方法
2019/09/19 Javascript
iview实现动态表单和自定义验证时间段重叠
2021/01/10 Javascript
[06:07]DOTA2-DPC中国联赛 正赛 Ehome vs VG 选手采访
2021/03/11 DOTA
六个窍门助你提高Python运行效率
2015/06/09 Python
Python3中lambda表达式与函数式编程讲解
2019/01/14 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
使用python计算三角形的斜边例子
2020/04/15 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
凯特方迪化妆品官网:Kat Von D Beauty
2016/11/15 全球购物
FORZIERI澳大利亚站:全球顶级奢华配饰精品店
2016/12/31 全球购物
在C中是否有模拟继承等面向对象程序设计特性的好方法
2012/05/22 面试题
文案策划求职信
2014/03/18 职场文书
公司踏青活动方案
2014/08/16 职场文书
学习党的群众路线实践活动思想汇报
2014/09/12 职场文书
向雷锋同志学习倡议书
2015/04/27 职场文书