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 实现对Map进行键值自定义排序
Apr 28 Golang
解决go在函数退出后子协程的退出问题
Apr 30 Golang
解决golang结构体tag编译错误的问题
May 02 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
go goroutine 怎样进行错误处理
Jul 16 Golang
golang实现一个简单的websocket聊天室功能
Oct 05 Golang
Go语言基础map用法及示例详解
Nov 17 Golang
Go语言读取txt文档的操作方法
Jan 22 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Golang 切片(Slice)实现增删改查
Apr 22 Golang
GoFrame框架数据校验之校验结果Error接口对象
Jun 21 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 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学习笔记 面向对象中[接口]与[多态性]的应用
2011/06/16 PHP
php字符串截取函数用法分析
2014/11/25 PHP
PHP中的替代语法介绍
2015/01/09 PHP
如何修改Laravel中url()函数生成URL的根地址
2017/08/11 PHP
Laravel框架实现利用中间件进行操作日志记录功能
2018/06/06 PHP
JavaScript触发器详解
2007/03/10 Javascript
js select常用操作控制代码
2010/03/16 Javascript
JavaScript访问样式表代码
2010/10/15 Javascript
jQuery中delegate与on的用法与区别示例介绍
2013/12/20 Javascript
jquery复选框全选/取消示例
2013/12/30 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
基于canvas实现的钟摆效果完整实例
2016/01/26 Javascript
JS实现n秒后自动跳转的两种方法
2020/11/30 Javascript
在windows上用nodejs搭建静态文件服务器的简单方法
2016/08/11 NodeJs
前端js弹出框组件使用方法
2020/08/24 Javascript
jquery广告无缝轮播实例
2017/01/05 Javascript
原生JS实现《别踩白块》游戏(兼容IE)
2017/02/20 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
react实现一个优雅的图片占位模块组件详解
2017/10/30 Javascript
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
Python中使用PyQt把网页转换成PDF操作代码实例
2015/04/23 Python
python实现内存监控系统
2021/03/07 Python
Sanic框架应用部署方法详解
2018/07/18 Python
Python基于mysql实现学生管理系统
2019/02/21 Python
学习python需要有编程基础吗
2020/06/02 Python
opencv 图像腐蚀和图像膨胀的实现
2020/07/07 Python
在 Windows 下搭建高效的 django 开发环境的详细教程
2020/07/27 Python
python常量折叠基础知识点讲解
2021/02/28 Python
美国著名手表网站:Timepiece
2017/11/15 全球购物
C#笔试题和英文面试题
2013/02/07 面试题
测试驱动开发的主要步骤是什么
2014/12/10 面试题
爱国演讲稿500字
2014/05/04 职场文书
2014年大学宣传部工作总结
2014/12/19 职场文书
2015年音乐教研组工作总结
2015/07/22 职场文书
劳动模范获奖感言
2015/07/31 职场文书