Last active
August 11, 2024 15:06
-
-
Save podhmo/b472609ee211f520c519fb4eda7d3cb7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// https://pkg.go.dev/plugin | |
// need: go build -buildmode=plugin | |
import ( | |
"fmt" | |
_ "m/x" | |
) | |
var V int | |
func F() { fmt.Printf("Hello, number %d\n", V) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import _ "m/x" | |
type Person struct { | |
Name string | |
Age int | |
Father *Person | |
Mother *Person | |
} | |
func New(name string, age int) *Person { | |
return &Person{Name: name, Age: age} | |
} | |
func Empty() Person { | |
return Person{} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"m/shape" | |
_ "m/x" | |
) | |
func New(name string, age int) *shape.Person { | |
return &shape.Person{Name: name, Age: age} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module m | |
go 1.22.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"m/shape" | |
"plugin" | |
) | |
func main() { | |
useA() | |
fmt.Println("----------------------------------------") | |
useB() | |
fmt.Println("----------------------------------------") | |
useC() | |
} | |
func useA() { | |
p, err := plugin.Open("bin/.plugin_a.so") | |
if err != nil { | |
panic(err) | |
} | |
v, err := p.Lookup("V") | |
if err != nil { | |
panic(err) | |
} | |
f, err := p.Lookup("F") | |
if err != nil { | |
panic(err) | |
} | |
*v.(*int) = 7 | |
f.(func())() // prints "Hello, number 7" | |
} | |
func useB() { | |
// p, err := plugin.Open("bin/.plugin_b.so") | |
// if err != nil { | |
// panic(err) | |
// } | |
// // panic: runtime error: invalid memory address or nil pointer dereference | |
// { | |
// sym, err := p.Lookup("Empty") | |
// if err != nil { | |
// panic(err) | |
// } | |
// // Use unsafe to convert the symbol to the correct type | |
// empty := *(*func() shape.Person)(unsafe.Pointer(&sym)) | |
// ob := empty() | |
// fmt.Printf("Empty: %v\n", ob) | |
// } | |
// // interface conversion: plugin.Symbol is func(string, int) *main.Person, not func(string, int) *main.Person (types from different scopes) | |
// { | |
// sym, err := p.Lookup("New") | |
// if err != nil { | |
// panic(err) | |
// } | |
// newPerson := sym.(func(string, int) *shape.Person) | |
// person := newPerson("Alice", 30) | |
// fmt.Printf("Person: %+v\n", person) | |
// } | |
} | |
func useC() { | |
p, err := plugin.Open("bin/.plugin_c.so") | |
if err != nil { | |
panic(err) | |
} | |
sym, err := p.Lookup("New") | |
if err != nil { | |
panic(err) | |
} | |
newPerson := sym.(func(string, int) *shape.Person) | |
person := newPerson("Alice", 30) | |
fmt.Printf("Person: %+v\n", person) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
default: clean | |
mkdir -p bin | |
tree > tree.out | |
go build -buildmode=plugin -o bin/.plugin_a.so ./plugins/a | |
go build -buildmode=plugin -o bin/.plugin_b.so ./plugins/b | |
go build -buildmode=plugin -o bin/.plugin_c.so ./plugins/c | |
go build -o bin/foo ./ | |
./bin/foo | |
clean: | |
rm -rf bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package shape | |
type Person struct { | |
Name string | |
Age int | |
Father *Person | |
Mother *Person | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
. | |
├── Makefile | |
├── bin | |
├── go.mod | |
├── main.go | |
├── plugins | |
│ ├── a | |
│ │ └── a.go | |
│ ├── b | |
│ │ └── b.go | |
│ └── c | |
│ └── c.go | |
├── shape | |
│ └── shape.go | |
├── tree.out | |
└── x | |
└── x.go | |
8 directories, 9 files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package x | |
import "fmt" | |
var V = 10 | |
func init() { | |
V++ | |
fmt.Println("on init, V is", V) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment