0Pricing
Go Academy · Lesson

Dynamic Loading and Symbols

Loading plugins at runtime and calling exported symbols

Dynamic Loading and Symbols is a free Go Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

plugin.Open

plugin.Open(path) loads a compiled .so file. It initialises the plugin's init() functions and package-level variables, then makes symbols available.

p, err := plugin.Open("./plugins/mymodule.so")
if err != nil { log.Fatalf("load: %v", err) }

p.Lookup

p.Lookup(name) finds an exported symbol by name. It returns an any; type-assert to the expected type.

sym, err := p.Lookup("NewProcessor")
if err != nil { log.Fatalf("lookup: %v", err) }
fn, ok := sym.(func() Processor)
if !ok { log.Fatal("wrong type") }

Loading multiple plugins

Load each .so from a directory and register them in a loop:

entries, _ := os.ReadDir("./plugins")
for _, e := range entries {
    if !strings.HasSuffix(e.Name(), ".so") { continue }
    p, err := plugin.Open("./plugins/" + e.Name())
    if err != nil { log.Printf("skip %s: %v", e.Name(), err); continue }
    loadPlugin(p)
}

Factory function pattern

Plugins export a factory function (NewXxx() Processor) rather than a value, so the host gets a fresh instance per call:

sym, _ := p.Lookup("NewProcessor")
factory := sym.(func() Processor)
proc := factory() // new instance

Error handling on lookup

Lookup errors mean the symbol is not exported or the name is wrong. Handle gracefully — skip the plugin or log and continue loading others.

plugin.Open is idempotent

Calling plugin.Open on the same path twice returns the same plugin. The plugin is only initialised once.

Lazy loading

Load plugins on demand (first use) rather than at startup to reduce startup time. Use a sync.Once per plugin to ensure it is loaded exactly once.

var mu sync.Mutex
var loaded = map[string]*plugin.Plugin{}

func getPlugin(path string) (*plugin.Plugin, error) {
    mu.Lock(); defer mu.Unlock()
    if p, ok := loaded[path]; ok { return p, nil }
    p, err := plugin.Open(path)
    if err != nil { return nil, err }
    loaded[path] = p
    return p, nil
}

Symbol naming conventions

Use capitalised CamelCase names for exported symbols (Go's visibility rule applies). Common convention: Plugin for the main value or New for the factory.

Handling plugin panics

If a plugin panics, the recover middleware in the host may catch it, but the plugin's goroutines may be in an undefined state. Log and skip the plugin; do not retry.

Validating plugin metadata

After loading, check a metadata symbol (e.g., PluginVersion string) to validate compatibility before registering:

ver, _ := p.Lookup("PluginVersion")
if *ver.(*string) != expectedVersion { log.Fatal("incompatible") }

Quick Check

What happens if you call plugin.Open twice with the same path?

Recap: Dynamic Loading and Symbols

Key points:

  • plugin.Open loads .so; p.Lookup returns any → type-assert
  • Load plugins from a directory in a loop for a plugin system
  • plugin.Open is idempotent; init() runs once per path
  • Prefer factory functions over value symbols for fresh instances

Frequently asked questions

Is the “Dynamic Loading and Symbols” lesson free?

Yes — the full text of “Dynamic Loading and Symbols” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Dynamic Loading and Symbols”?

Loading plugins at runtime and calling exported symbols You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Dynamic Loading and Symbols” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Go plugin Package Basics
  2. Designing a Plugin Interface
  3. Dynamic Loading and Symbols
  4. Alternatives: HashiCorp go-plugin
← Back to Go Academy