英文:
Golang 1.8 plugin.Lookup only loads first plugin
问题
我正在使用Golang编写一个规则引擎。我的测试涉及构建和加载两个插件,这些插件执行一些非常简单的字符串比较操作。我通过执行文件匹配并调用plugin.Open()
来加载插件,到目前为止一切顺利,我们得到了两个不同的对象。但是,当我调用plug.Lookup(symbol)
时,返回的符号始终是对第一个插件的引用。
我已经调试过了,确保插件是不同的对象,它们确实是不同的,但是符号查找并没有按预期工作。
这里是一个虚构的工作示例:
main.go
package main
import "plugin"
import "fmt"
func main() {
aPlug, _ := plugin.Open("testdata/plugins/a.so")
aSymPlug, _ := aPlug.Lookup("Rule")
fmt.Printf("Plugin: %v loaded\n", aSymPlug)
bPlug, _ := plugin.Open("testdata/plugins/b.so")
bSymPlug, _ := bPlug.Lookup("Rule")
fmt.Printf("Plugin: %v loaded\n", bSymPlug)
}
a.go插件
package main
type plugin string
func init() {
Rule = "a"
}
func (p plugin) String() string {
return string(p)
}
var Rule plugin
b.go插件
package main
type plugin string
func init() {
Rule = "b"
}
func (p plugin) String() string {
return string(p)
}
var Rule plugin
但是,当我将插件更改为返回字符串"a"或"b"(无论是哪个插件,或者两个插件都返回)而不是p
时,它加载了错误的插件!即:
package main
type plugin string
func init() {
Rule = "b"
}
func (p plugin) String() string {
return "b"
}
var Rule plugin
这将输出:
Plugin: a loaded
Plugin: a loaded
编辑:添加了示例代码
英文:
I'm writing a Rules Engine in Golang. My tests involve building and loading two plugins that do some very simple string comparison. I load the plugins by doing a fileglob and calling plugin.Open()
, so far so good we get two different objects back. But when I call plug.Lookup(symbol)
the symbol returned is always a reference to the first plugin.
DEBU[0000] Starting A rule
DEBU[0000] Starting A rule
I've debugged back to make sure the plugins are different objects, which they are, but the symbol lookup isn't working as expected.
Here's a contrived working example:
main.go
package main
import "plugin"
import "fmt"
func main() {
aPlug, _ := plugin.Open("testdata/plugins/a.so")
aSymPlug, _ := aPlug.Lookup("Rule")
fmt.Printf("Plugin: %v loaded\n", aSymPlug)
bPlug, _ := plugin.Open("testdata/plugins/b.so")
bSymPlug, _ := bPlug.Lookup("Rule")
fmt.Printf("Plugin: %v loaded\n", bSymPlug)
}
a.go plugin
package main
type plugin string
func init() {
Rule = "a"
}
func (p plugin) String() string {
return string(p)
}
var Rule plugin
b.go plugin
package main
type plugin string
func init() {
Rule = "b"
}
func (p plugin) String() string {
return string(p)
}
var Rule plugin
BUT when I change the plugin to return the string "a" or "b" (doesn't matter which plugin, either or both) instead of p
then it loads the wrong plugin! i.e.
package main
type plugin string
func init() {
Rule = "b"
}
func (p plugin) String() string {
return "b"
}
var Rule plugin
This outputs:
Plugin: a loaded
Plugin: a loaded
EDIT: Added example code
答案1
得分: 0
这是一个Golang的bug(参见https://github.com/golang/go/issues/20376)。
如Motakjuq所指出的,解决方法是更改类型的名称,以便每个插件都具有不同的类型。这样可以避免冲突。
英文:
This is a Golang bug (see https://github.com/golang/go/issues/20376)
The workaround, as pointed out by Motakjuq, is to change the name of the type so each plugin has a different type. This avoids the collision.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论