Go 语言的插件系统就是基于 程序的运行期间动态调用 实现的,也就是动态库或动态链接库。插件系统是基于 C 语言的动态库实现的。
示例
插件实现的两个函数 Add 和 Sub 在文件 func-plugin.go 里
package main
// go build -buildmode=plugin -o main.so func-plugin.go
import "fmt"
// Add two integers
func Add(a int, b int) int {
fmt.Printf("\nAdding a=%d and b=%d\n", a, b)
return a + b
}
// Sub two integers
func Sub(a int, b int) int {
fmt.Printf("\nSubtracting b= %d from a=%d\n", b, a)
return a - b
}
编译成动态库 go build -buildmode=plugin -o main.so func-plugin.go
写一个程序来调用 main.so
package main
import (
"fmt"
"path/filepath"
"plugin"
)
func main() {
plugins, err := filepath.Glob("main.so")
if err != nil {
panic(err)
}
fmt.Printf("Loading plugin %s\n", plugins[0])
// Open – Loads the plugin
p, err := plugin.Open(plugins[0])
if err != nil {
panic(err)
}
// Lookup – Searches for a symbol name in the plugin
add, err := p.Lookup("Add")
if err != nil {
panic(err)
}
// Checks the function signature
addFunc, ok := add.(func(i, j int) int)
if !ok {
panic("Plugin has no 'Add(int, int)int' function")
}
// Uses the function to return results
fmt.Printf("\n10 + 12 = %d\n", addFunc(10,12))
sub, err := p.Lookup("Sub")
if err != nil {
panic(err)
}
subFunc, ok := sub.(func(i, j int) int)
if !ok {
panic("Plugin has no 'Sub(int, int)int' function")
}
fmt.Printf("\n22 - 8 = %d\n", subFunc(22,8))
}