dlplugin

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2022 License: BSD-3-Clause Imports: 4 Imported by: 0

README

dlplugin

This package is based on the official Go plugin package, but modified to use any dynamic C libraries (Only Linux, FreeBSD, and macOS).

It provides a thread-safe interface for loading/unloading dynamic libraries, but the library symbols should be loaded manually using PluginInitializer.

Installation

go get github.com/Devoter/dlplugin

or use go mod tool.

Usage

WARNING: Windows implementation was not tested and should not be used.

This package uses cgo, it is highly recommended to read the official CGO documentation.

Open and prepare a plugin via dlplugin.Open() function:

Open(path string, initializer PluginInitializer) (*Plugin, error)

It accepts a library filename and an initializer. The Init() method denotes a function type which initializes a plugin API.

type PluginInitializer interface {
	Init(lookup func(symName string) (uintptr, error)) error
}

An opened library may be closed using the Close() method of the Plugin or the Close() function:

func (p *Plugin) Close() error

func Close(p *Plugin) error

Examples

All examples have Makefiles, therefore you can build each example with the make command.

Basic

This example is a program that prints "Hello, world!" via dynamic library call. The example contains two implementations of program: naive and with an interface.

Plugin code
package main

import "C"
import "fmt"

//export println
func println(v *C.char) {
	s := C.GoString(v)

	fmt.Println(s)
}

func main() {}

Program code
package main

/*
#include <stdint.h>
#include <stdlib.h>

static void println(uintptr_t r, char *s)
{
	((void (*)(char *))r)(s);
}
*/
import "C"
import (
	"flag"
	"fmt"
	"os"
	"unsafe"

	"github.com/Devoter/dlplugin"
)

type PluginAPI struct {
	Println func(s string)
}

// Init initializes the plugin API.
func (papi *PluginAPI) Init(lookup func(symName string) (uintptr, error)) error {
	printlnPtr, err := lookup("println")
	if err != nil {
		return err
	}

	papi.Println = func(s string) {
		cs := C.CString(s)
		defer C.free(unsafe.Pointer(cs))

		C.println(C.uintptr_t(printlnPtr), cs)
	}

	return nil
}

func main() {
	pluginFilename := flag.String("plugin", "", "plugin filename")
	help := flag.Bool("help", false, "show this text")

	flag.Parse()

	if *help {
		flag.PrintDefaults()
		return
	}

	var papi PluginAPI

	plug, err := dlplugin.Open(*pluginFilename, &papi)
	if err != nil {
		fmt.Fprintf(os.Stderr, "could not initialize a plugin by the reason: %v\n", err)
		os.Exit(1)
	}

	defer plug.Close()

	papi.Println("Hello, world!")
}

See.

Random values

This example starts a random values generator from the library and reads generated values.

See.

Callback

This example concatenates two string with a dynamic library and returns the result via a callback function.

See.

Multilib

This example loads two libs with the single interface. The program instanciates remote objects and works with them.

See

License

LICENSE

Documentation

Overview

Package dlplugin provides a thread-safe interface for loading/unloading dynamic libraries. The library symbols should be loaded manually using PluginInitializer interface.

Package dlplugin implements loading and symbol resolution of C plugins.

A plugin is a shared object (dynamic library) with exported functions and variables.

Currently plugins are only supported on Linux, FreeBSD, and macOS.

See examples in examples directory.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Close

func Close(p *Plugin) error

Close closes a plugin.

Types

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin is a loaded plugin.

func Open

func Open(path string, initializer PluginInitializer) (*Plugin, error)

Open opens a plugin. If a path has already been opened, then the existing *Plugin is returned. It is safe for concurrent use by multiple goroutines. If the initializer is nil the initialization process will be skipped.

func (*Plugin) Close

func (p *Plugin) Close() error

Close closes a plugin.

func (*Plugin) Init added in v1.0.1

func (p *Plugin) Init(initializer PluginInitializer) error

Init provides a lookup function and calls an initializer's Init method.

type PluginInitializer

type PluginInitializer interface {
	// Init initializes a plugin API.
	Init(lookup func(symName string) (uintptr, error)) error
}

PluginInitializer provides an interface which is used to initialize a plugin interface.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL