У меня есть Go файл с кодом ниже. Я скомпилировал это в файл плагина .so.
// +build engine
package main
func DoStuff(t interface { Do() }) {
t.Do()
}
Затем main. go, который его вызывает:
package main
import (
"fmt"
"plugin"
"reflect"
)
func main() {
plug, _ := plugin.Open("test.so")
testFunc, _ := plug.Lookup("DoStuff")
impl := Implementation{}
actualFunc, ok := testFunc.(func(d interface{ Do() }))
if !ok {
panic(reflect.TypeOf(testFunc))
}
actualFunc(impl)
}
Скомпилируйте и запустите с go build -buildmode=plugin -tags engine -o test.so ./ && go build . && ./test
. Этот подход работает отлично, и я получаю ожидаемое "работающее" эхо.
Если я изменю его на;
// +build engine
package main
type StuffInterface interface {
Do()
}
func DoStuff(t StuffInterface) {
t.Do()
}
для плагина и вызов на;
package main
import (
"fmt"
"plugin"
"reflect"
)
func main() {
plug, _ := plugin.Open("test.so")
testFunc, _ := plug.Lookup("DoStuff")
impl := Implementation{}
actualFunc, ok := testFunc.(func(d LocalInterface))
if !ok {
panic(reflect.TypeOf(testFunc))
}
actualFunc(impl)
}
type LocalInterface interface {
Do()
}
type Implementation struct { }
func (t Implementation) Do() {
fmt.Println("works")
}
Или вот так;
package main
import (
"fmt"
"plugin"
"reflect"
)
func main() {
plug, _ := plugin.Open("test.so")
testFunc, _ := plug.Lookup("DoStuff")
impl := Implementation{}
actualFunc, ok := testFunc.(func(d interface{ Do() }))
if !ok {
panic(reflect.TypeOf(testFunc))
}
actualFunc(impl)
}
type Implementation struct { }
func (t Implementation) Do() {
fmt.Println("works")
}
он больше не работает, и я получаю пани c, которая печатает мне ожидаемый тип;
go build -buildmode=plugin -tags engine -o test.so ./ && go build . && ./test
panic: func(main.StuffInterface)
goroutine 1 [running]:
main.main()
/Users/dennis/test/main.go:17 +0x171
Может кто-нибудь объяснить, почему это не работает с другими 2 подходами? Go интерфейсы неявные, поэтому я понимаю, что это должно работать.