首页 > 解决方案 > Can go plugins' symbols be interchangeable?

问题描述

An example:

lib1/lib.go

package lib
type MyInt int

plugin1.go

package main
import lib "./lib1"
func GetMyInt() lib.MyInt {
return lib.MyInt(1)
}

lib2/lib.go and plugin2.go

lib2/lib.go is same contents as lib1/lib.go. plugin2.go is same contents as plugin1.go, except it imports "./lib2" instead of "./lib1"

Both plugins are compiled as follows:

$ go build -buildmode=plugin plugin1.go
$ go build -buildmode=plugin plugin2.go

loader.go

package main
import lib "./lib1"
import "plugin"
func main() {
    plugin2,_ := plugin.Open("plugin2.so")
    symbol,_ := plugin2.Lookup("GetMyInt")
    myfunc := symbol.(func() lib.MyInt)
    println(myfunc())
}
$ go run loader.go

The results

This results in the panic:

panic: interface conversion: plugin.Symbol is func() lib.MyInt, not func() lib.MyInt (types from different scopes)

It seems Go doesn't like the idea of having two different import paths when asserting types from identical libraries.

However, this is a problem with what I'm dealing with. I've got a library with various types that will be used by other programmer's work ("plugins"). My software will then load the various plugins and assert the types against the same library. However, must I really force them to use the same GOPATH imports (ie, force them to use the same central github import path)? I like relative imports because it allows the programmer to use flexible project structures.

I would think that if the asserted type is completely identical to the memory footprint as the imported symbol, then it shouldn't panic as it technically makes it a valid symbol. I also want then to be able to make extensions to the library I distribute, which causes another panic being that the asserted types are of "different versions".

Is there no way for me to designate that lib1's types and lib2's types can be asserted against eachother?

标签: gopluginssymbols

解决方案


推荐阅读