预备知识
plugin模式
插件运行方式
go plugin包使用
相关知识(推荐:go语言教程)
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.gopackage mainimport "fmt"func hello(){ fmt.println("hello")}// go build -buildmode=plugin -o hello.so hello.go// soft/basetype.gopackage mainimport ( "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.gopackage itftype printor interface{ print(v interface{})}//------------------------------------------------------// plugins/p1.gopackage mainimport ( "fmt" "softplugin/itf")type screenprintor struct{}func (screenprintor)print(v interface{}){ fmt.println("p1p1 ",v)}func install() printor{ return &screenprintor{}}//-----------------------------------------------------// soft/s1.gopackage mainimport ( "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") } }
以上就是go生成go动态库或静态库的方法的详细内容。