Golang筆記-Plugin初探

來源:互聯網
上載者:User

前言

最近在學習fabric 1.2版本的新特性,其中有一個是實現了交易背書和區塊結果驗證這兩個原本由系統鏈碼esccvscc負責的模組的可插拔。它們的可插拔用到了Go的plugin技術,這也是我第一次知道Go Plugin的概念(雖然在Go 1.8版本就有了),於是準備探一探究竟Go Plugin是什麼,怎麼用。

什麼是Go Plugin

Golang是靜態編譯型語言,在編譯時間就將所有引用的包(庫)全部載入打包到最終的可執行程式(或庫檔案)中,因此並不能在運行時動態載入其他共用庫。Go Plugin提供了這樣一種方式,能夠讓你在運行時動態載入外部功能。

為什麼用Go Plugin

其實應該問為什麼要用Plugin,我覺得原因有很多,比如:

  • 可插拔:有了Plugin,我的程式可以根據需要隨時替換其中某些組件而不用修改我的程式;
  • 動態載入的需要:有些模組只有在運行時才能確定,需要動態載入外部的功能模組;
  • 獨立開發:Plugin 可以和主程式獨立建設,主程式只需要制定好架構,實現預設(模版)功能。Plugin 可根據使用者需求隨時自行擴充開發,運行時隨意替換,提高了程式的可定製性;

怎麼用Go plugin

Golang 對 Plugin 的實現在標準庫plugin中。整個介面可以說相當簡潔了。

type Plugin struct{ ... }    func Open(path string) (*Plugin, error)    func (p *Plugin) Lookup(symName string) (Symbol, error)type Symbol interface{}

是的,你沒有看錯,就只有兩個type和兩個方法。

Plugin

type Plugin即Golang載入的外掛程式,與之有關的兩個方法:

  • Open: 根據參數path提供的外掛程式路徑載入這個外掛程式,並返回外掛程式這個外掛程式結構的指標*Glugin
  • Lookup: *Plugin的惟一方法,通過名稱symName在外掛程式中尋找對應的變數或方法,以Symbol的形式返回

Symbol

根據定義type Symbol interface{}Symbolinterface的別名,也就是說,我們可以從外掛程式裡面拿到任何類型的可匯出元素。

小試牛刀

瞭解了plugin包的準系統,按照慣例,我們要用hello world檢驗下。
準備plugin源碼pluginhello.go

package mainimport (    "fmt")func Hello() {    fmt.Println("Hello World From Plugin!")}

這裡在外掛程式中,定義了一個可匯出方法Hello列印Hello World From Plugin!
有了源碼,怎樣將他編譯成一個外掛程式呢?

➜  plugin go1.10 build --buildmode=plugin -o pluginhello.so pluginhello.go➜  plugin lsinvokeplugin.go pluginhello.go  pluginhello.so

go build命令,同時制定buildmodeplugin即可。So Easy!
注意:這裡尤其要注意的是,plugin的源碼需要在main包中,否則無法編譯。

下面該調用這個外掛程式了:

package mainimport (    "fmt"    "os"    "plugin")func main() {    p, err := plugin.Open("./pluginhello.so")    if err != nil {        fmt.Println("error open plugin: ", err)        os.Exit(-1)    }    s, err := p.Lookup("Hello")    if err != nil {        fmt.Println("error lookup Hello: ", err)        os.Exit(-1)    }    if hello, ok := s.(func()); ok {        hello()    }}

首先通過Open方法開啟外掛程式,然後通過名稱Hello找到外掛程式中的func Hello方法。
注意,由於從外掛程式中找到的任何元素都是以Symbol形式(即interface{})返回,我們需要通過斷言的形式對結果進行判斷和轉換,得到我們需要的類型。
讓我們看看效果吧:

➜  plugin go1.10 run invokeplugin.goHello World From Plugin!

完美調用了外掛程式!

說明: Go 1.8時 Plugin 支援Linux和macOS,但是因為bug在1.9取消了對macOS的支援,1.10時又恢複了對macOS的支援。
我的機器上因為裝了多個版本,而開發需要常用的是go 1.9,所以這裡使用go 1.10時,命令用的go1.10這個軟串連

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.