Go当前的插件API不支持发现和使用未知插件。你必须know插件和知道会发生什么来自它(包括导出符号的类型)。
有一天,API 可能会针对您正在寻找的内容进行添加,但目前(Go 1.9.2)您只能使用Plugin.Lookup() only.
“Hack”查看导出的符号
加载的插件由 type 的值表示*plugin.Plugin。这是指向包含符号表的结构的指针,但未导出。如果您想“查看”导出了哪些符号,您可以使用fmt打包打印它。
我将使用此答案中的插件示例:go 1.8插件使用自定义接口,即:
type plgFilter struct{}
func (plgFilter) Name() string { return "Bob" }
func (plgFilter) Age() int { return 23 }
func GetFilter() (f filter.Filter, err error) {
f = plgFilter{}
fmt.Printf("[plugin GetFilter] Returning filter: %T %v\n", f, f)
return
}
它包含一个导出符号:GetFilter
功能。加载并打印该插件的符号表:
p, err := plugin.Open("pg/pg.so")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", p)
我们可以“观察”导出的GetFilter
输出中的符号:
&{pluginpath:pg loaded:0xc420020120 syms:map[GetFilter:0x7f0a7fddc860]}
这个符号的关联值是一个内存地址,不太多说。
但我们可以做更多:我们可以使用 packagereflect在我们查找之后打印它的类型:
GetFilter, err := p.Lookup("GetFilter")
if err != nil {
panic(err)
}
fmt.Println(reflect.TypeOf(GetFilter))
现在我们会看到:
func() (filter.Filter, error)
我们看到它是一个有 2 个返回类型的函数:filter.Filter
and error
.