demo示例:
aplugin.go
package main func Add(x, y int) int { return x + y } func Subtract(x, y int) int { return x - y }
创建插件aplugin.so :
go build -buildmode=plugin -o aplugin.so aplugin.go
test.go
package main import ( "fmt" "plugin" ) var ( ProductObj *plugin.Plugin ) //编写一个"构造函数"(单例模式,懒汉模式) func new() *plugin.Plugin { if ProductObj == nil { ProductObj, _ = plugin.Open("./aplugin.so") } return ProductObj } func AddNum(x, y int) int { p := new() add, _ := p.Lookup("Add") sum := add.(func(int, int) int)(x, y) return sum } func main() { sum := AddNum(11, 2) fmt.Print(sum) }
前面的是使用懒汉模式的单例模式,并不是线程安全的,可以用golang的init()来模仿饿汉模式
test.go
package main import ( "fmt" "product" ) func main() { sum := product.AddNum(11, 2) fmt.Print(sum) }
product.go
package product import ( "fmt" "plugin" ) func init(){ go new() } var ( ProductObj *plugin.Plugin ) //编写一个"构造函数"(单例模式,懒汉模式) func new() *plugin.Plugin { if ProductObj == nil { ProductObj, _ = plugin.Open("./aplugin.so") } return ProductObj } func AddNum(x, y int) int { p := new() add, _ := p.Lookup("Add") sum := add.(func(int, int) int)(x, y) return sum }
以上代码是线程安全的,因为程序一开始就调用了product 包的init()来执行new。
要理解以上代码需要清楚golang main和init的调用顺序。
其他package的init() > main package包的main > main package包的init()