go - 插件和包范围的全局变量

标签 go plugins

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

pakage config

var gConfig ...

func init() {
    gConfig = ...
}

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

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

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

最佳答案

根据文档

Package plugin implements loading and symbol resolution of Go plugins. When a plugin is first opened, the init functions of all packages not already part of the program are called. The main function is not run. A plugin is only initialized once, and cannot be closed.

此外,您不能两次导入相同的插件。

Will the plugin have its own internal instance of config with its own gConfig variable initialized when the plugin is loaded

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

If the plugin imports the config package and calls some of its exported functions, what gConfig variable will be used ?

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

要检查这一点,请编写一个小演示。 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

关于go - 插件和包范围的全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58769757/

相关文章:

Golang os.使用嵌套目录创建路径

go - 在Golang中实现XSS防护

java - 运行时使用的代码是否有自动突出显示

c# - 使用 IE 插件浏览器帮助程序对象 (BHO) 访问 Frame 或 Iframe 中的数据

ruby-on-rails - 无法使用 AnyCable 通过 websocket 连接 Rails 和 Go

google-app-engine - 将 *Key 存储到 GAE 本地数据存储在 DataStoreViewer 中给我错误

grails - 如何从Request中检索cxf Web服务中的 header 参数?

.NET 插件安全

http - 在 Go 中返回一个值而不是一个指针

javascript - 如何将js小部件添加到 Shiny 的仪表板