package main // #include // #include // for free // #include "caller.h" // #cgo LDFLAGS: -ldl import "C" import ( "log" "path/filepath" "time" "unsafe" ) // Loop trough the plugin path to load any .so func main() { for { matches, err := filepath.Glob("plugins/bin/*.so") panicIfErr(err) for _, v := range matches { execPlugin(v) } <-time.After(3 * time.Second) } } func execPlugin(plugpath string) { defer func() { if q := recover(); q != nil { log.Println("Recovering panic") } }() plugname := C.CString(plugpath) phandle := C.dlopen(plugname, C.RTLD_NOW) // Win32 LoadLibrary if phandle == nil { cerr := C.dlerror() log.Println("err:", C.GoString(cerr)) C.free(unsafe.Pointer(cerr)) } C.free(unsafe.Pointer(plugname)) cs := C.CString("Add") // Find our Add implementation sym := C.dlsym(phandle, cs) C.free(unsafe.Pointer(cs)) if sym == nil { // Not thread safe since is fetching error after call (another dl might be called in between) cerr := C.dlerror() log.Println("err:", C.GoString(cerr)) C.free(unsafe.Pointer(cerr)) } r := C.call(sym, 1, 2) res := C.GoString(r) log.Printf("From: %-30s Result --> '%s'", plugpath, res) C.free(unsafe.Pointer(r)) //log.Println("Res:", C.GoString(C.testLocal())) /**/ C.dlclose(phandle) } func panicIfErr(err error) { if err != nil { panic(err) } }