Golang中的插件开发

插件化开发提供了很多便利,可动态扩展程序的相关功能,如Windows中的DLL、Linux中的So文件、还有IDEA中的插件,应用范围不可谓不广;
在Golang中提供了自己的插件机制,可使用其进行插件化开发;在Golang的plugin包中提供了加载插件、调用插件中函数的相关方法;

Golang中的插件机制使用非常简单;就只有这么三步:
1、编写插件库相关代码,生成so文件;
2、加载插件so文件;
3、调用相关的函数或字段;
下面用一个简单例子来看看插件的基本使用:

这个插件非常简单,定义一个公开的字段V,一个公开的函数F。

package main
import “fmt”

var V int
func F(){
  fmt.Printf(“Hello Plugin: %d\n”,V)
}

生成so文件也和之前编译普通的go文件一样只是多了个参数;
go build -buildmode=plugin demo.go
执行上诉命令后将生成一个名为:demo.so的插件库文件;

有了插件现在到了使用插件,使用插件也没啥难度,具体代码如下:

p,err := plugin.Open(“demo.so”)
if err!=nil{
   panic(err)
}
v,err := p.Lookup(“V”)  //调用插件中的V字段
if err!=nil{
   panic(err)
}
f,err :=p.Lookup(“F”)  //调用插件中的F函数
if err!=nil{
   panic(err)
}
*v.(*int) = 100
f.(fun())()        //类型断言,f为一个无参无返回值的函数fun(),然后调用函数f

插件调用的输出结果为:Hello Plugin: 100

插件使用:

插件与主程序使用的接口必须是同一个
通常使用流程:
1、定义依赖的包文件,包含相关的接口等;
2、插件实现上述所定义的接口
3、主程序应用依赖包,调用插件实现;

package lib
type Calculator interface {
  Add(int, int) int
  Sub(int, int) int
}
package main
import (
 "demo/lib"
)
type Call struct {}
func (c *Call) Sub(a, b int) int {
 return a - b
}
func (c *Call) Add(a, b int) int {
 return a + b
}
func NewCal() lib.Calculator {
  return &Call{}
}
package main
import (
  "demo/lib"
  "fmt"
  "plugin"
)
p, err := plugin.Open("plugin/operation_plugin.so")
if err != nil {
   panic(err)
}
cal,err:= p.Lookup("NewCal")
if err != nil {
  panic(err)
}
c:= cal.(func ()lib.Calculator)()
fmt.Println(c.Add(3,5))
fmt.Println(c.Sub(20,10))

注意事项:
编译插件所使用的参数必须与编译主程序所使用参数一直,否则将可能出现如下异常信息:

panic: plugin.Open("plugin/operation_plugin"): plugin was built with a different version of package runtime/internal/sys

如在编译插件库so文件时使用了-gcflags all=-N -l 参数,禁止优化、禁止内联,则主程序调用插件时也必须加上;

Original: https://www.cnblogs.com/softlin/p/14560711.html
Author: AiFly
Title: Golang中的插件开发

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/584489/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球