【问题标题】:plugin and package scoped global variables插件和包范围的全局变量
【发布时间】:2019-11-09 16:34:12
【问题描述】:

我有一个 Go 包来管理配置。该包有一个在保存配置数据的init 函数中初始化的非导出变量。用户通过内部访问全局变量的导出函数与配置进行交互。像这样的

pakage config

var gConfig ...

func init() {
    gConfig = ...
}

func Value(name string) (string, error) {
    return gConfig.value(name)
}

我正在考虑使用插件并探索对我的配置包的影响。

如果插件导入 config 包并调用其导出的一些函数,将使用什么 gConfig 变量?插件是否有自己的内部配置实例,并在插件加载时初始化其自己的 gConfig 变量,或者插件在加载时动态链接以使用在程序启动时初始化的主程序 gConfig 变量?

【问题讨论】:

  • 让配置包导出一个可以复制到插件的结构不是更明确吗?我认为你的问题的答案是他们都会访问同一个变量,但我认为如果是这样,那么这种设计有一定的魔力,很难解释未发起的(可能是未来的你)。它越明确,就越可维护。 FWIW

标签: go plugins


【解决方案1】:

根据文档

包插件实现了 Go 插件的加载和符号解析。 当一个插件第一次打开时,所有包的init函数不 程序的一部分已经被调用。主函数未运行。 插件只初始化一次,不能关闭

此外,您不能两次导入同一个插件。

插件是否会拥有自己的内部配置实例,并在插件加载时初始化其自己的 gConfig 变量

插件将在其范围内拥有自己的变量。

如果插件导入 config 包并调用其导出的部分函数,​​将使用什么 gConfig 变量?

包中定义的变量,如您所演示的。

要检查这一点,请编写一个小型演示。 Go 非常简单高效,只需很少的时间,看看。

    $ tree .
    .
    ├── main.go
    ├── plug
    │   └── plugin.go
    └── plugin.so

    1 directory, 3 files
// $ cat plug/plugin.go 
package main

var pkgGlobal = map[string]string{}

func Set(k, v string) {
    pkgGlobal[k] = v
}
func Get(k string) string {
    return pkgGlobal[k]
}
// $ cat main.go 
package main

import (
    "fmt"
    "plugin"
)

func main() {
    p, err := plugin.Open("plugin.so")
    if err != nil {
        panic(err)
    }
    var get func(string) string
    {
        x, err := p.Lookup("Get")
        if err != nil {
            panic(err)
        }
        get = x.(func(string) string)
    }
    var set func(string, string)
    {
        x, err := p.Lookup("Set")
        if err != nil {
            panic(err)
        }
        set = x.(func(string, string))
    }

    set("tomate", "rouge")
    fmt.Println(get("tomate"))
    fmt.Println(get("notomate"))
}

构建并运行

$ go build -buildmode=plugin -o plugin.so plug/plugin.go 
$ go run main.go 
rouge

【讨论】:

  • 感谢您提供如此详细的答案。不幸的是,它只部分回答了我的问题。使用您的代码示例,我实现了我正在考虑的精确用例,并且可以验证插件没有另一个包的全局变量的副本。因此,我可以使用插件中的配置包而不会发生冲突。非常感谢。
猜你喜欢
  • 2013-05-26
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多