Golang 1.8 plugin.Lookup 只加载第一个插件。

huangapple go评论74阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年5月15日 19:18:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/43978124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定