dlopen.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package main
  2. // #include <dlfcn.h>
  3. // #include <stdlib.h> // for free
  4. // #include "caller.h"
  5. // #cgo LDFLAGS: -ldl
  6. import "C"
  7. import (
  8. "log"
  9. "path/filepath"
  10. "time"
  11. "unsafe"
  12. )
  13. // Loop trough the plugin path to load any .so
  14. func main() {
  15. for {
  16. matches, err := filepath.Glob("plugins/bin/*.so")
  17. panicIfErr(err)
  18. for _, v := range matches {
  19. execPlugin(v)
  20. }
  21. <-time.After(3 * time.Second)
  22. }
  23. }
  24. func execPlugin(plugpath string) {
  25. defer func() {
  26. if q := recover(); q != nil {
  27. log.Println("Recovering panic")
  28. }
  29. }()
  30. plugname := C.CString(plugpath)
  31. phandle := C.dlopen(plugname, C.RTLD_NOW) // Win32 LoadLibrary
  32. if phandle == nil {
  33. cerr := C.dlerror()
  34. log.Println("err:", C.GoString(cerr))
  35. C.free(unsafe.Pointer(cerr))
  36. }
  37. C.free(unsafe.Pointer(plugname))
  38. cs := C.CString("Add")
  39. // Find our Add implementation
  40. sym := C.dlsym(phandle, cs)
  41. C.free(unsafe.Pointer(cs))
  42. if sym == nil { // Not thread safe since is fetching error after call (another dl might be called in between)
  43. cerr := C.dlerror()
  44. log.Println("err:", C.GoString(cerr))
  45. C.free(unsafe.Pointer(cerr))
  46. }
  47. r := C.call(sym, 1, 2)
  48. res := C.GoString(r)
  49. log.Printf("From: %-30s Result --> '%s'", plugpath, res)
  50. C.free(unsafe.Pointer(r))
  51. //log.Println("Res:", C.GoString(C.testLocal())) /**/
  52. C.dlclose(phandle)
  53. }
  54. func panicIfErr(err error) {
  55. if err != nil {
  56. panic(err)
  57. }
  58. }