Home | History | Annotate | Download | only in plugin
      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Package plugin implements loading and symbol resolution of Go plugins.
      6 //
      7 // Currently plugins only work on Linux.
      8 //
      9 // A plugin is a Go main package with exported functions and variables that
     10 // has been built with:
     11 //
     12 //	go build -buildmode=plugin
     13 //
     14 // When a plugin is first opened, the init functions of all packages not
     15 // already part of the program are called. The main function is not run.
     16 // A plugin is only initialized once, and cannot be closed.
     17 package plugin
     18 
     19 // Plugin is a loaded Go plugin.
     20 type Plugin struct {
     21 	pluginpath string
     22 	loaded     chan struct{} // closed when loaded
     23 	syms       map[string]interface{}
     24 }
     25 
     26 // Open opens a Go plugin.
     27 // If a path has already been opened, then the existing *Plugin is returned.
     28 // It is safe for concurrent use by multiple goroutines.
     29 func Open(path string) (*Plugin, error) {
     30 	return open(path)
     31 }
     32 
     33 // Lookup searches for a symbol named symName in plugin p.
     34 // A symbol is any exported variable or function.
     35 // It reports an error if the symbol is not found.
     36 // It is safe for concurrent use by multiple goroutines.
     37 func (p *Plugin) Lookup(symName string) (Symbol, error) {
     38 	return lookup(p, symName)
     39 }
     40 
     41 // A Symbol is a pointer to a variable or function.
     42 //
     43 // For example, a plugin defined as
     44 //
     45 //	package main
     46 //
     47 //	// // No C code needed.
     48 //	import "C"
     49 //
     50 //	import "fmt"
     51 //
     52 //	var V int
     53 //
     54 //	func F() { fmt.Printf("Hello, number %d\n", V) }
     55 //
     56 // may be loaded with the Open function and then the exported package
     57 // symbols V and F can be accessed
     58 //
     59 //	p, err := plugin.Open("plugin_name.so")
     60 //	if err != nil {
     61 //		panic(err)
     62 //	}
     63 //	v, err := p.Lookup("V")
     64 //	if err != nil {
     65 //		panic(err)
     66 //	}
     67 //	f, err := p.Lookup("F")
     68 //	if err != nil {
     69 //		panic(err)
     70 //	}
     71 //	*v.(*int) = 7
     72 //	f.(func())() // prints "Hello, number 7"
     73 type Symbol interface{}
     74