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文件

  生成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 參數,禁止優化、禁止內聯,則主程序調用插件時也必須加上;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM