Go生成go動態庫或靜態庫
阿新 • • 發佈:2018-12-06
Go生成go動態庫或靜態庫
預備知識
- plugin模式
- 外掛執行方式
- go plugin包使用
相關知識
go build 可以指定buildmode。分為了多種模式。具體模式如下。
模式 | 說明 |
---|---|
當前go版本 | 1.10.3 |
archive | 編譯成二進位制檔案。一般是靜態庫檔案。 xx.a |
c-archive | 編譯成C歸檔檔案。C可呼叫的靜態庫。xx.a。注意要編譯成此類檔案需要import C 並且要外部呼叫的函式要使用 “//export 函式名” 的方式在函式上方註釋。否則函式預設不會被匯出。 |
c-shared | 編譯成C共享庫。同樣需要 import “C” 和在函式上方註釋 // export xxx |
default | 對於有main包的直接編譯成可執行檔案。沒有main包的,編譯成.a檔案 |
exe | 編譯成window可執行程式 |
plugin | 將main包和依賴的包一起編譯成go plugin。非main包忽略。【類似C的共享庫或靜態庫。外掛式開發使用】 |
例項
結構: -softplugin //根目錄 -soft //軟體目錄 -plugins //外掛目錄 -itf //介面目錄
無自定義資料
// plugins/hello.go
package main
import "fmt"
func Hello(){
fmt.Println("hello")
}
// go build -buildmode=plugin -o hello.so hello.go
// soft/basetype.go
package main
import (
"os"
"path"
"plugin"
"fmt"
)
func main(){
//載入外掛
pluginDir := "../plugins"
//掃描資料夾下所有so檔案
f, err := os.OpenFile(pluginDir, os.O_RDONLY, 0666)
if err != nil {
panic(err)
}
fi, err := f.Readdir(-1)
if err != nil {
panic(err)
}
plugins := make([]os.FileInfo, 0)
for _, ff := range fi {
if ff.IsDir() || path.Ext(ff.Name()) != ".so" {
continue
}
plugins = append(plugins, ff)
pdll, err := plugin.Open(pluginDir + "/" + ff.Name())
if err != nil {
fmt.Println(err)
continue
}
plg, err := pdll.Lookup("Hello")
if err != nil {
panic(err)
}
plg.(func())()
}
}
// go run basetype.go
定義外掛介面 interface。
//------------------------------------------------------
// itf/itf1.go
package itf
type Printor interface{
Print(v interface{})
}
//------------------------------------------------------
// plugins/p1.go
package main
import (
"fmt"
"softplugin/itf"
)
type ScreenPrintor struct{}
func (ScreenPrintor)Print(v interface{}){
fmt.Println("p1p1 ",v)
}
func Install() Printor{
return &ScreenPrintor{}
}
//-----------------------------------------------------
// soft/s1.go
package main
import (
"softplugin/itf"
"os"
"path"
"plugin"
"fmt"
)
var(
printors = make([]itf.Printor, 0)
)
func main(){
//載入外掛
pluginDir := "../plugins"
//掃描資料夾下所有so檔案
f, err := os.OpenFile(pluginDir, os.O_RDONLY, 0666)
if err != nil {
panic(err)
}
fi, err := f.Readdir(-1)
if err != nil {
panic(err)
}
plugins := make([]os.FileInfo, 0)
for _, ff := range fi {
if ff.IsDir() || path.Ext(ff.Name()) != ".so" {
continue
}
plugins = append(plugins, ff)
pdll, err := plugin.Open(pluginDir + "/" + ff.Name())
if err != nil {
fmt.Println(err)
continue
}
plg, err := pdll.Lookup("Hello")
if err != nil {
panic(err)
}
printors = append(printors, (plg.(func() itf.Printor))())
}
for _, p := range printors {
p.Print("pppp")
}
}