Skip to content

Repository files navigation

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(pathstring, initializerPluginInitializer) (*Plugin, error)

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

typePluginInitializerinterface {
Init(lookupfunc(symNamestring) (uintptr, error)) error
}

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

func (p*Plugin) Close() errorfuncClose(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 printlnfuncprintln(v*C.char) {
s:=C.GoString(v)
fmt.Println(s)
}
funcmain() {}
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"
)
typePluginAPIstruct {
Printlnfunc(sstring)
}
// Init initializes the plugin API.func (papi*PluginAPI) Init(lookupfunc(symNamestring) (uintptr, error)) error {
printlnPtr, err:=lookup("println")
iferr!=nil {
returnerr
}
papi.Println=func(sstring) {
cs:=C.CString(s)
deferC.free(unsafe.Pointer(cs))
C.println(C.uintptr_t(printlnPtr), cs)
}
returnnil
}
funcmain() {
pluginFilename:=flag.String("plugin", "", "plugin filename")
help:=flag.Bool("help", false, "show this text")
flag.Parse()
if*help {
flag.PrintDefaults()
return
}
varpapiPluginAPIplug, err:=dlplugin.Open(*pluginFilename, &papi)
iferr!=nil {
fmt.Fprintf(os.Stderr, "could not initialize a plugin by the reason: %v\n", err)
os.Exit(1)
}
deferplug.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

About

Go C-based plugins loader

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages