Symbolic Interface Implementation in Plugin
In Go plugins, importing a plugin with an external interface poses challenges when attempting to return the interface as a plugin function response. This behavior is not straightforward, but can be understood through the examination of plugin variables and interfaces.
Plugin Variable Types
A plugin's variable, such as "Greeter" in your example, exists as a pointer to its declared type. Therefore, using the Lookup function will return a pointer to the variable, not its value. This becomes important when trying to type assert an interface from the obtained value.
Interface Typing
When attempting to type assert an interface (e.g., iface.IPlugin) from a pointer to that interface (e.g., *iface.IPlugin), you will encounter an error. This is because a value of a pointer type to an interface never satisfies any interfaces except the empty interface.
Resolution
To resolve this issue, there are two approaches:
Dereferencing the Pointer:
Instead of type asserting from a pointer to an interface, you should dereference the pointer first to obtain the value and then attempt type assertion. For example:
pgPtr, ok := sym.(*iface.IPlugin) if !ok { panic(errors.New("error binding plugin to interface")) } pg := *pgPtr
Exposing a Function:
To avoid the complexity of pointer dereferencing, consider exposing a function in the plugin that returns the interface implementation. The plugin variable "Greeter" would then become a function that takes no arguments and returns iface.IPlugin.
Code Example
Here's the second approach implemented in your plugin:
func Greeter() iface.IPlugin { return testpl{} }
And the corresponding lookup and usage 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() fmt.Printf("You're now connected to: %s \n", greeter.WhatsYourName()) greeter.SayHello("user") greeter.SayGoodby("user")
This approach simplifies the process of obtaining the interface implementation from the plugin and allows you to avoid the nuances of pointer handling.
The above is the detailed content of How Can I Successfully Return an Interface from a Go Plugin?. For more information, please follow other related articles on the PHP Chinese website!