Golang官方如何支持加载动态库
来源:互联网 发布:网络舆论的传播分析 编辑:程序博客网 时间:2024/06/08 17:24
Golang1.8官方支持加载动态库了,而且看起来功能很强大。 文档上面描述Plugin功能是协程并发安全的,而且支持高级数据类型(包括chan),同时不需要写任何C代码(以前或多或少需要写一些)。
下面我们通过一些demo来看看如何使用golang plugin功能
入门
下面是一个简单的plugin 代码:
package main// // No C code needed.import "C"import ( "fmt")var V intfunc F() { fmt.Printf("Hello, number %d\n", V) }
这是官方提供的例子,以后我们再慢慢扩展。
go build -buildmode=plugin main.go //main.go是plugin文件名称,你可以改成其它名
你会看到多出一个main.so动态库。
然后我们开始调用这个动态库
package mainimport ( "plugin")func main() { p, err := plugin.Open("main.so") if err != nil { panic(err) } v, err := p.Lookup("V") if err != nil { panic(err) } f, err := p.Lookup("F") if err != nil { panic(err) } *v.(*int) = 7 f.(func())()
正常编译这个go文件,然后执行它就可以看到屏幕会输出
Hello, number 7
这只是最简单的形式,下面我们增加一些难度,使用一些复杂数据类型。
使用复杂类型
我们自定义一个结构体
package datatype VS struct { Name string Age int School string}
这里需要注意,必须要把结构体放到另外一个package中,否则build plugin时,会抱结构体找不到。
然后我们开始修改plugin代码
package main// // No C code needed.import "C"import ( "fmt" "temp/data")var V intfunc F() { fmt.Printf("Hello, number %d\n", V) }var Vs data.VSfunc ComplexType() { fmt.Println(Vs.Name, Vs.Age, Vs.School)}
我们声明了VS结构体,然后增加了一个函数用来使用结构体(需要重新编译plugin)。 调用方也需要同步修改
package mainimport ( "plugin" "temp/data")func main() { p, err := plugin.Open("main.so") if err != nil { panic(err) } v, err := p.Lookup("V") if err != nil { panic(err) } f, err := p.Lookup("F") if err != nil { panic(err) } *v.(*int) = 7 f.(func())() // prints "Hello, number 7" vs, err := p.Lookup("Vs") if err != nil { panic(err) } ct, err := p.Lookup("ComplexType") if err != nil { panic(err) } *vs.(*data.VS) = data.VS{ Name: "DATA", Age: 11, School: "BEIDA", } ct.(func())()}
在main中我们构建了一个VS结构体,然后给各个属性赋值。 如果正常,你将看到如下的信息
Hello, number 7DATA 11 BEIDA
到此为止,我们已经可以在Plugin中使用高级复杂结构体了,可以说已经满足50%需求了。 但探索无止境,如果调用和Plugin之间需要互相通讯怎么办?下面我们看看Plugin是否支持Chan。
支持Chan
首先声明一个全局Chan
package datatype VS struct { Name string Age int School string}var Msg = make(chan VS)
不但声明了一个全局chan,而且是高级类型的chan。 下面在Plugin中使用chan
package main// // No C code needed.import "C"import ( "fmt" "temp/data")var V intfunc F() { fmt.Printf("Hello, number %d\n", V) }var Vs data.VSfunc ComplexType() { fmt.Println(Vs.Name, Vs.Age, Vs.School) Vs.Age = Vs.Age * 4 data.Msg <- Vs}
Plugin接收到vs数据后,将AGE放大4倍在扔出去(扔哪里就不管了)(需要重新编译plugin)。 再修改一下调用函数:
package mainimport ( "plugin" "temp/data")func main() { p, err := plugin.Open("main.so") if err != nil { panic(err) } v, err := p.Lookup("V") if err != nil { panic(err) } f, err := p.Lookup("F") if err != nil { panic(err) } *v.(*int) = 7 f.(func())() // prints "Hello, number 7" vs, err := p.Lookup("Vs") if err != nil { panic(err) } ct, err := p.Lookup("ComplexType") if err != nil { panic(err) } *vs.(*data.VS) = data.VS{ Name: "DATA", Age: 11, School: "BEIDA", } go ct.(func())() select { case m := <-data.Msg: println(m.Age) }}
其实是在main函数中接受扔回来的VS结构体。 编译之后再执行,可以看到
Hello, number 7DATA 11 BEIDA44
OK,执行正常,符合预期。 这里先提供plugin如何使用,以后我们再剖析一下Golang是如何实现这些功能的。
- Golang官方如何支持加载动态库
- golang以插件的方式加载golang动态库
- golang调用动态库
- VC++如何加载动态库
- linux如何动态加载动态库
- wince动态加载字体支持
- Linux下如何动态加载,卸载库
- 如何编写可动态加载库
- 如何动态加载控件?
- 如何动态加载图片
- linux下如何动态加载动态库(loadlibrary)
- golang官方学习文档
- 动态加载菜单(仅支持二级菜单)
- 二.动态模块加载(DSO)支持
- 用VC++实现软件的多语种支持及动态库动态加载
- 动态加载动态库
- 动态加载动态库
- 如何动态加载JS脚本
- Solr查询流程
- Mysql 问题总结
- Qt之操作Excel(2)
- [Codeforces 147B Smile House] DP+倍增+二分
- LeetCode 122. Best Time to Buy and Sell Stock II
- Golang官方如何支持加载动态库
- SSL JudgeOnline 1455——电子老鼠闯迷宫
- 简单ajax坑我好几次
- [编程题]蛇形矩阵
- 【李木华】算法与数据结构概述
- 数组和链表的区别
- C# 泛型类型参数的约束
- java for语句案例
- 【数据库开发】在Windows上利用C++开发MySQL的初步