When attempting to import a plugin that implements an interface defined outside both packages, binding the plugin symbol to an interface fails. This occurs despite the plugin's struct implementation of the interface.
The issue arises from the approach of looking up a variable from the plugin, which returns a pointer to that variable. To type assert an interface from a value of pointer type to interface never succeeds. Instead, the solution is to export a function from the plugin that returns the desired interface type.
func Greeter() iface.IPlugin { return testpl{} }
The plugin package operates by returning pointers to values when looking up variables. For a variable of type iface.IPlugin, this results in a pointer to an interface, which cannot be type asserted to iface.IPlugin.
By returning a function from the plugin, the lookup operation no longer requires a pointer. The function can then be invoked to obtain the desired interface value.
To utilize this approach, the plugin definition should be updated to expose a function that returns the interface implementation. The program can then lookup this function and use it to obtain the greeter instance.
// In the plugin func Greeter() iface.IPlugin { return testpl{} } // In the main program Greeter, err := p.Lookup("Greeter") if err != nil { panic(err) } greeterFunc, ok := Greeter.(func() iface.IPlugin) if !ok { panic(errors.New("not of expected type")) } greeter := greeterFunc()
This approach avoids the hassle of indirect type assertions and confusion caused by the use of pointers. Additionally, it aligns with a more intuitive way of exposing functionality from a plugin.
The above is the detailed content of Why Does Returning a Plugin Symbol as a Function Solve Go Plugin Interface Binding Issues?. For more information, please follow other related articles on the PHP Chinese website!