2017-04-12 55 views
1

go1.8以上,go支持创建并加载插件。golang:如何卸载已经加载的“go插件”1.8

但不支持卸载插件。

插件是在运行时加载的模块,是否可以卸载模块?

如果无法卸载模块,在应用程序级别可以完成卸载插件的最佳做法/使其不可用,但仍在内存中?

+0

对于标题感到抱歉,所以强迫我多次修改它,因为它不符合质量标准 – weima

+0

您无法“卸载”插件。你可以以某种方式版本插件,所以你可以每次加载新的插件? – JimB

+0

为什么不向你的插件添加一个Unload函数? –

回答

0

Go不支持卸载插件。但是,您可以按照您的建议禁用它。通常一个插件会定义一个包含插件信息的结构体。您可能会从具有众所周知的名称的工厂功能中返回此名称(例如awesome.so包含AwesomePlugin)。您可以在结构中包含的其中一项是禁用对插件的访问的方法。你可以做这样的事情:

type MyPlugin struct { 
    Name string 
    Enable func() error 
    Disable func() error 
} 

然后在插件本身你会做这样的事情:

var (
    awesomeEnabled bool 
) 

func AwesomePlugin() *myplugin.MyPlugin { 
    return &myplugin.MyPlugin{ 
     Name: "AwesomePlugin", 
     Enable: func() error { 
      println("Enabling AwesomePlugin") 
      awesomeEnabled = true 
      return nil // or do something more complex that could error 
     }, 
     Disable: func() error { 
      println("Disabling AwesomePlugin") 
      awesomeEnabled = false 
      return nil // or do something more complex that could error 
     }, 
    } 
} 

然后代码加载它,打开它,并禁用它会是这样像:

awesomePlugin, err := plugin.Open("awesome.so") 
if err != nil { 
    panic("Can't load plugin: " + err.Error()) 
} 

sym, err := awesomePlugin.Lookup("AwesomePlugin") 
if err != nil { 
    panic("Can't find symbol: " + err.Error()) 
} 

awesomeFactory := sym.(func() *myplugin.MyPlugin) 
awesome := awesomeFactory() 

println("Loaded " + awesome.Name + " plugin") 

err = awesome.Enable() 
if err != nil { 
    panic("Can't enable plugin: " + err.Error()) 
} 

// Do some stuff 

err = awesome.Disable() 
if err != nil { 
    panic("Can't enable plugin: " + err.Error()) 
} 

你必须在插件看看代码,看看是否已启用插件或不运行可以定义任何其他功能之前。

然后运行它,我们得到这样的输出:

Loaded AwesomePlugin plugin 
Enabling AwesomePlugin 
Disabling AwesomePlugin 

显然,你不想panic()无处不在。这只是一个用于处理错误的占位符。