這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
環境
系統: linux (別問為什麼,因為windows下golang不支援動態庫)
golang版本: 1.5 以上支援動態庫,1.8以上支援plugin
外掛程式代碼
外掛程式代碼跟普通的golang模組代碼沒啥差別,主要是package必須是 main。下面是一段簡易的外掛程式代碼
//testplugin.gopackage mainimport ( "fmt")func init() { fmt.Println("world") //我們還可以做其他更高階的事情,比如 platform.RegisterPlugin({"func": Hello}) 之類的,向外掛程式平台自動註冊該外掛程式的函數}func Hello() { fmt.Println("hello")}
init 函數的目的是在外掛程式模組載入的時候自動執行一些我們要做的事情,比如:自動將方法和類型註冊到外掛程式平台、輸出外掛程式資訊等等。
Hello 函數則是我們需要在調用方顯式尋找的symbol
編譯命令
go build -buildmode=plugin testplugin.go
編譯完後我們可以看到目前的目錄下有一個 testplugin.so 檔案
我們也可以通過類似如下命令來產生不同版本的外掛程式
go build -o testplugin_v1.so -buildmode=plugin testplugin.go
如果要想更好的控制外掛程式的版本,想做更酷的事情,比如:熱更新外掛程式。那麼可以採用自動註冊的方式,新版本的外掛程式載入上來後,自動註冊外掛程式版本號碼,外掛程式平台裡優先使用新版本的方法。
使用
使用方需要引入 plugin 這個包
//main.gopackage mainimport ( "plugin")func main() { p, err := plugin.Open("testplugin.so") if err != nil { panic(err) } f, err := p.Lookup("Hello") if err != nil { panic(err) } f.(func())()}
輸出
$ go run main.go worldhello
我們可以看到,我們只顯式調用了外掛程式中的Hello方法,列印hello這個字串,但是在調用Hello之前,已經輸出了world,這個正是外掛程式init函數做的事情。
總結
golang支援外掛程式使得golang程式的擴充性上升到另一個台階,可以用來做更酷的事情,如:利用外掛程式做服務的熱更新