You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.5 KiB

  1. //+build !windows
  2. package plugin
  3. import (
  4. "errors"
  5. "fmt"
  6. "io/fs"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "plugin"
  11. )
  12. // LoadPlugin 加载插件 传入path
  13. func LoadPlugin(path string) error {
  14. path, err := filepath.Abs(path)
  15. if err != nil {
  16. return err
  17. }
  18. fileInfo, err := os.Stat(path)
  19. if err != nil {
  20. return err
  21. }
  22. if fileInfo.IsDir() {
  23. fileSlice, err := ioutil.ReadDir(path)
  24. if err != nil {
  25. return err
  26. }
  27. for _, ff := range fileSlice {
  28. if !ff.IsDir() && filepath.Ext(ff.Name()) == ".so" {
  29. if err = loadPlugin(path, ff); err != nil {
  30. return err
  31. }
  32. } else if ff.IsDir() {
  33. _ = LoadPlugin(filepath.Join(path, ff.Name()))
  34. }
  35. }
  36. return nil
  37. } else {
  38. return loadPlugin(path, fileInfo)
  39. }
  40. }
  41. func loadPlugin(path string, f fs.FileInfo) error {
  42. if filepath.Ext(f.Name()) == ".so" {
  43. fPath := filepath.Join(path, f.Name())
  44. // 加载插件
  45. p, err := plugin.Open(fPath)
  46. if err != nil {
  47. fmt.Println("loadPlugin err ", err)
  48. return err
  49. }
  50. // 判断是否满足协议
  51. // 要满足 OnlyFuncName && 实现 Plugin 接口
  52. if v, err := p.Lookup(OnlyFuncName); err != nil {
  53. fmt.Println("loadPlugin err ", err)
  54. return err
  55. } else if _, ok := v.(Plugin); !ok {
  56. fmt.Println("loadPlugin err ", fmt.Sprintf("path:%s 没有实现 %s 接口", filepath.Base(fPath), OnlyFuncName))
  57. return errors.New("没有实现指定接口")
  58. } else {
  59. }
  60. fmt.Println("loadPlugin add ", filepath.Base(fPath))
  61. ManagementPlugin.SetPlugin(filepath.Base(fPath), p)
  62. }
  63. return nil
  64. }