Home  >  Article  >  Backend Development  >  How to Share Custom Data Types Between Go Plugins and the Main Application?

How to Share Custom Data Types Between Go Plugins and the Main Application?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-28 00:23:29801browse

How to Share Custom Data Types Between Go Plugins and the Main Application?

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn