Fork me on GitHub
随笔 - 215  文章 - 13  trackbacks - 0
<2017年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234


专注即时通讯及网游服务端编程
------------------------------------
Openresty 官方模块
Openresty 标准模块(Opm)
Openresty 三方模块
------------------------------------
本博收藏大部分文章为转载,并在文章开头给出了原文出处,如有再转,敬请保留相关信息,这是大家对原创作者劳动成果的自觉尊重!!如为您带来不便,请于本博下留言,谢谢配合。

常用链接

留言簿(1)

随笔分类

随笔档案

相册

Awesome

Blog

Book

GitHub

Link

搜索

  •  

积分与排名

  • 积分 - 204280
  • 排名 - 127

最新评论

阅读排行榜

来自:http://blog.csdn.net/andylau00j/article/details/53769446
Golang1.8官方支持加载动态库了,而且看起来功能很强大。 文档上面描述Plugin功能是协程并发安全的,而且支持高级数据类型(包括chan),同时不需要写任何C代码(以前或多或少需要写一些)。


下面我们通过一些demo来看看如何使用golang plugin功能
入门
下面是一个简单的plugin 代码:
package main
// // No C code needed.
import "C"
import (
    "fmt"
)
var V int
func F() { fmt.Printf("Hello, number %d\n", V) }
这是官方提供的例子,以后我们再慢慢扩展。
go build -buildmode=plugin  main.go  //main.go是plugin文件名称,你可以改成其它名
你会看到多出一个main.so动态库。
然后我们开始调用这个动态库
package main
import (
    "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 data
type 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 int
func F() { fmt.Printf("Hello, number %d\n", V) }
var Vs data.VS
func ComplexType() {
    fmt.Println(Vs.Name, Vs.Age, Vs.School)
}
我们声明了VS结构体,然后增加了一个函数用来使用结构体(需要重新编译plugin)。 调用方也需要同步修改
package main
import (
    "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 7
DATA 11 BEIDA
到此为止,我们已经可以在Plugin中使用高级复杂结构体了,可以说已经满足50%需求了。 但探索无止境,如果调用和Plugin之间需要互相通讯怎么办?下面我们看看Plugin是否支持Chan。
支持Chan
首先声明一个全局Chan
package data
type 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 int
func F() { fmt.Printf("Hello, number %d\n", V) }
var Vs data.VS
func ComplexType() {
    fmt.Println(Vs.Name, Vs.Age, Vs.School)
    Vs.Age = Vs.Age * 4
    data.Msg <- Vs
}
Plugin接收到vs数据后,将AGE放大4倍在扔出去(扔哪里就不管了)(需要重新编译plugin)。 再修改一下调用函数:
package main
import (
    "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 7
DATA 11 BEIDA
44
OK,执行正常,符合预期。 这里先提供plugin如何使用,以后我们再剖析一下Golang是如何实现这些功能的。

官方文档:golang插件机制(plugin)
https://tip.golang.org/pkg/plugin/?utm_source=tuicool&utm_medium=referral
posted on 2017-01-19 18:44 思月行云 阅读(2225) 评论(0)  编辑 收藏 引用 所属分类: Golang

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理