I'm writing a simple app which loads plugin in a predefined format. Example plugin is the following:
package main
import (
"errors"
"fmt"
"strings"
)
var (
ok bool
InvConfig = errors.New("invalid config")
)
type Processor struct {
logEverything bool
}
func (p *Processor) Init(config map[string]interface{}) error {
p.logEverything, ok = config["log_everything"].(bool)
if !ok {
return InvConfig
}
return nil
}
func (p *Processor) Process(buf []byte) []byte {
if p.logEverything {
fmt.Printf("Shouter got data: %v\n", buf)
}
return []byte(strings.ToUpper(string(buf)))
}
func GetProcessor() *Processor {
return &Processor{}
}
I can't quite apprehend how to load such a structure in my main program. So, I declare an interface:
type Processor interface {
Init(map[string]interface{}) error
Process(buf []byte) []byte
}
Then I load "getter" function and try to cast it to a function returning interface to then call it:
p, err := plugin.Open(filepath)
if err != nil {
logrus.Fatalf("Error opening plugin %s: %v", pluginName, err)
}
procGetterInter, err := p.Lookup("GetProcessor")
if err != nil {
logrus.Fatalf("Error loading processor getter for plugin %s: %v", pluginName, err)
}
procGetter, ok := procGetterInter.(func() interface{})
if !ok {
logrus.Fatalf("Error casting processor getter for plugin %s: %T", pluginName, procGetterInter)
}
But the cast fails with an error:
Error casting processor getter for plugin simple_shout: func() *main.Processor
If I return an actual instance (not a pointer) from GetProcessor
and try to cast the function to the one returning Processor
, I get the same result:
Error casting processor getter for plugin simple_shout: func() main.Processor
How to get a struct instance from plugin (therefore load the function returning it) and type-assert it's an expected interface in my case?
UPD: If I remove everything from Processor
interface (that is, it becomes just an empty interface):
type Processor interface {}
And try to cast procGetterInter
to a function returning a pointer to Processor
interface:
procGetter, ok := procGetterInter.(func() *Processor)
I still get the same error:
plugin.Symbol is func() *main.Processor, not func() *main.Processor (types from different scopes)
Why doesn't it cast even to pointer to an empty interface?