go: 插件系统

参考文章: https://toutiao.io/posts/adjoci/preview

闲来无事,今天发现go居然有一个插件系统。 果然是宇宙级的语言。

配置文件

plugconf.yaml

plug:
  lang: "./pluglib/en.so"

load.go 载入插件

package plug

import (
    "github.com/ghodss/yaml"
    "io/ioutil"
    "plugin"
)
import "xxxxxxx/checkerr"

var GlobalGreeter func() string

type Plugconf struct {
    Plug struct {
        Lang string
    }
}

var GlobalPlugconf *Plugconf

func Load() (err error) {
    defer checkerr.MarkPanic(&err)

    // 载入配置文件
    modByte, err := ioutil.ReadFile("./conf/plugconf.yaml")
    checkerr.CheckError(err, "load conf failed", err)
    // 解析配置
    GlobalPlugconf = new(Plugconf)
    err = yaml.Unmarshal(modByte, GlobalPlugconf)
    checkerr.CheckError(err, "marshal yaml failed ", err)

    // 打开插件
    plug, err := plugin.Open(GlobalPlugconf.Plug.Lang)
    checkerr.CheckError(err, "open plug failed", err)

    // 寻找对象
    greeterObj, err := plug.Lookup("Greeter")
    checkerr.CheckError(err, "look up failed ", err)

    // 转换对象的格式
    GlobalGreeter = greeterObj.(func() string)

    return nil
}

func RunGreeter() string {
    return GlobalGreeter()
}

main函数调用

package main

import (
    "fmt"
    "main/plug"
    "time"
)

func main() {
    for {
        err := plug.Load()
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(plug.RunGreeter())
        time.Sleep(time.Second)
    }
}

插件编写

插件需要在main包。比如

ch.go

package main

type greeter struct {
}

func (g *greeter) Greet() string {
    return "世界你好"
}

// 这个就是可导出的函数,插件在lookup这个函数
func Greeter() string {
    return new(greeter).Greet()
}

en.go

package main

type greeter struct {
}

func (g *greeter) Greet() string {
    return "hello world"
}

func Greeter() string {
    return new(greeter).Greet()
}

make插件

插件代码写好后,必须编译为so Makefile

all:lib
lib:
    go build -buildmode=plugin -o ./en.so en.go
    go build -buildmode=plugin -o ./ch.so ch.go

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • go:文件按行读取

    超级大猪
  • 容器:namespace文件隔离实现

    参考资料: 自己动手写docker-4 https://juejin.im/post/5c2b495af265da6134388142 使用golang理...

    超级大猪
  • Python笔记:装饰器(面向切面)

    http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

    超级大猪
  • Go进阶37:重构我的base64Captcha图形验证码项目

    ?Base64captcha? 几行代码就可以定义自己内容的图形验证码库,支持任意unicode字符的内容.

    mojocn
  • Golang 语言 Web 框架 beego v2 之控制器方法和输入输出数据

    创建 beego 的控制器,首先要匿名组合 beego.Controller,beego.Controller实现了接口 beego.ControllerInt...

    frankphper
  • 机器学习VS放射科医生

    编译:张小阳博士 斯坦福大学的研究人员开发出一种机器学习的算法,CheXnet。它能比放射科医生更好地利用胸部X片诊断肺炎,而且在短短一个月内就完成了超越。 实...

    企鹅号小编
  • 对深度网络的神经体系结构搜索方法的建模(CS CV)

    针对深度神经网络(DNN)结构设计的研究较多,它们被称为神经结构搜索(NAS)方法。虽然有很多自动和手动的方法来解决NAS问题,但是没有一个统一的模型来研究和比...

    DANDAN用户6837186
  • KubeEdge - edgecore edgehub模块源码分析

    在模块启动时先将拿到beehiveContext,然后获取EdgehubConfig

    有点技术
  • 3D-BoNet:3D 点云实例分割的新框架 | NeurIPS 2019

    本文对牛津大学、DeepMind 等单位合作完成的论文《Learning Object Bounding Boxes for 3D Instance Segme...

    AI科技评论
  • GitHub 消息邮件通知太烦人?收下这份指南!

    经常有朋友反馈说邮箱被 GitHub 的消息通知狂轰滥炸,各种无关的邮件提醒搞得很烦。

    猿天地

扫码关注云+社区

领取腾讯云代金券