Custom Data Type Sharing in Go Plugins
In Go, you can define custom data types in plugins. However, sharing these data types between a plugin and the main application requires careful consideration.
The Limitations of Symbol Lookup
When accessing exported symbols from a plugin, you can type assert them into an interface. However, directly type asserting them into a struct is not possible using symbol lookup alone.
A Custom Data Type as an Example
Let's consider the following example:
<code class="go">// plugin.go package main type Person struct { Name string } var P Person = Person{ Name: "Emma", }</code>
<code class="go">// app.go package main import ( "fmt" "os" "plugin" ) func main() { plug, err := plugin.Open("./plugin.so") if err != nil { fmt.Println(err) os.Exit(1) } sym, err := plug.Lookup("P") if err != nil { fmt.Println(err) os.Exit(1) } var p Person p, ok := sym.(Person) if !ok { fmt.Println("Wrong symbol type") os.Exit(1) } fmt.Println(p.Name) // Panic: "Wrong symbol type" }</code>
In this example, the P symbol is a Person struct. However, the type assertion in the main app fails with an error.
The Solution: Separate Type Definition
The key to sharing custom data types between a plugin and the main application is to define the type separately. This way, both the plugin and the main app can refer to the same type definition.
Example with Separate Type Definition
<code class="go">// type.go package filter type Filter struct { Name string Age int }</code>
<code class="go">// plugin.go package main import "play/filter" var MyFilter filter.Filter = filter.Filter{ Name: "Bob", Age: 21, } func CreateFilter() filter.Filter { return filter.Filter{ Name: "Bob", Age: 21, } }</code>
<code class="go">// app.go package main import ( "fmt" "log" "os" "play/filter" "plugin" ) func main() { p, err := plugin.Open("plugin.so") if err != nil { log.Fatal(err) } mf, err := p.Lookup("MyFilter") if err != nil { log.Fatal(err) } f, ok := mf.(*filter.Filter) if !ok { log.Fatal("Wrong symbol type") } fmt.Printf("%+v\n", f) // Output: &{Name:Bob Age:21} }</code>
By defining the Filter type in a separate package, the plugin and the main app can both import it and use it for type assertions.
The above is the detailed content of How to Share Custom Data Types Between Go Plugins and the Main Application?. For more information, please follow other related articles on the PHP Chinese website!