在1.8之前楔脯,如果我們想用第三方的庫撩轰,只能獲取到源碼才可以,而不能使用編譯后的代碼昧廷,比如jar堪嫂、dll、so文件木柬。不過1.8中新加入了plugin包皆串,我們可以通過這個包來實現(xiàn)調(diào)用、訪問編譯后方法和變量的功能弄诲,不過到目前版本(1.11.1)為止還不支持windows(幾年沒碰過這超惡心的os了愚战,真嗨森。齐遵。。)塔插。
plugin 是一個包含可導出(首字母大寫)函數(shù)和變量的main包梗摇。當一個plugin首次被打開的時候,是在所有包中的init方法已經(jīng)調(diào)用完成之后想许,main方法執(zhí)行之前伶授。一個plugin只會被初始化一次断序,并且不會被關(guān)閉。plugin的操作都是協(xié)程安全的糜烹。
下面我們將會舉個例子說明plugin包如何使用(類型轉(zhuǎn)換违诗,函數(shù)傳參調(diào)用,修改變量的值)疮蹦。plugin.go:
package main
import "fmt"
func Say(str string) string{
return fmt.Sprintf("Hello, my name is: %s, addr is: %s\n",str,Addr)
}
var Addr = "default home address"
編譯plugin需要使用-buildmode=plugin參數(shù)诸迟,編譯后是一個.so文件:
go build --buildmode=plugin plugin.go
看一下caller.go:
package main
import (
"fmt"
"os"
"plugin"
)
func main() {
p, err := plugin.Open("plugin.so")
if err != nil {
panic(err)
}
sb, err := p.Lookup("Say")
if err != nil {
panic(err)
}
sbs := sb.(func(string) string)
if len(os.Args) > 2 {
str, err := p.Lookup("Addr")
if err != nil {
panic(err)
}
*str.(*string) = os.Args[2]
}
fmt.Println(sbs(os.Args[1]))
}
如果運行main的時候,有一個參數(shù)愕乎,則將參數(shù)傳遞給plugin中的Say方法(調(diào)用plugin函數(shù))阵苇;如果有兩個或以上的參數(shù),則第二個參數(shù)將會替換掉plugin中的Addr變量的值(修改plugin變量)感论。例如:
go run caller.go jingege
#Hello, my name is: jingege, addr is: default home address
go run caller.go jingege chengdu
#Hello, my name is: jingege, addr is: chengdu
注意
- 1绅项、plugin必須是在main包下,即 package mian
- 2比肄、編譯plugin的時候快耿,必須使用--buildmode=plugin參數(shù)
- 3、Lookup只能查找可導出的成員(方法芳绩,變量等)润努,并且返回參數(shù)為指針,需要轉(zhuǎn)換成對應(yīng)的類型才能使用