1
0
Fork 0
go_plugin_demo/cmd/demo.go
Frédéric G. MARAND be1f9236e0 Code and findings updated for go 1.27.3.
tl;dr:
- Linux debugging works
- macOS running works, debugging doesn't.
2026-11-02 17:17:20 +01:00

85 lines
2 KiB
Go

package main
import (
"fmt"
"log"
"math/rand"
"path/filepath"
"plugin"
"code.osinet.fr/fgm/go_plugin_demo"
)
func loadPlugins(names []string) (map[string]*plugin.Plugin, error) {
plugins := make(map[string]*plugin.Plugin)
for _, name := range names {
plug, err := plugin.Open(filepath.Join("plugins", name, name+".so"))
if err != nil {
return nil, fmt.Errorf("failed opening plugin %q: %w", name, err)
}
plugins[name] = plug
}
return plugins, nil
}
/*
Name obtains the name of a plugin.
*/
func Name(p *plugin.Plugin) (string, error) {
const symbolName = "InternalName"
var nameSymbol plugin.Symbol
nameSymbol, err := p.Lookup(symbolName)
if err != nil {
return "", fmt.Errorf("could not find %q in plugin %q: %w",
symbolName, nameSymbol, err)
}
pName, ok := nameSymbol.(*string)
if !ok {
return "", fmt.Errorf(`symbol %q was not a string`, symbolName)
}
return *pName, nil
}
func Work(p *plugin.Plugin, n uint) (string, error) {
const symbolWork = "Work"
var workSymbol plugin.Symbol
workSymbol, err := p.Lookup(symbolWork)
if err != nil {
return "", fmt.Errorf("could not find %q in plugin %q: %w",
symbolWork, workSymbol, err)
}
work, ok := workSymbol.(*go_plugin_demo.Worker)
if !ok {
return "", fmt.Errorf(`symbol %q was not a Worker`, symbolWork)
}
res := (*work)(n)
return res, err
}
func main() {
names := []string{"foo", "bar"}
plugins, err := loadPlugins(names)
if err != nil {
log.Fatalf("failed loading plugins: %v", err)
}
for range 10 {
for name, plug := range plugins {
quantity := uint(rand.Intn(4))
internalName, err := Name(plug)
if err != nil {
log.Fatalf("Failed getting internal name for plugin %q: %v", name, err)
}
fmt.Printf("Sending %d units of work to %s\t", quantity, internalName)
res, err := Work(plug, quantity)
if err != nil {
log.Fatalf("Failed getting %d units of work from plugin %q: %v",
quantity, name, err)
}
fmt.Printf("Result from %q: %q\n", internalName, res)
}
}
}