plugin_uinx.go 1.5 KB
Newer Older
S
songzhibin97 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//+build !windows

package plugin

import (
	"errors"
	"fmt"
	"io/fs"
	"io/ioutil"
	"os"
	"path/filepath"
	"plugin"
)

// LoadPlugin 加载插件 传入path
func LoadPlugin(path string) error {
	path, err := filepath.Abs(path)
	if err != nil {
		return err
	}
	fileInfo, err := os.Stat(path)
	if err != nil {
		return err
	}
	if fileInfo.IsDir() {
		fileSlice, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}
		for _, ff := range fileSlice {
			if !ff.IsDir() && filepath.Ext(ff.Name()) == ".so" {
				if err = loadPlugin(path, ff); err != nil {
					return err
				}
			} else if ff.IsDir() {
				_ = LoadPlugin(filepath.Join(path, ff.Name()))
			}
		}
		return nil
	} else {
		return loadPlugin(path, fileInfo)
	}
}

func loadPlugin(path string, f fs.FileInfo) error {
	if filepath.Ext(f.Name()) == ".so" {
		fPath := filepath.Join(path, f.Name())
		// 加载插件
		p, err := plugin.Open(fPath)
		if err != nil {
			fmt.Println("loadPlugin err ", err)
			return err
		}
		// 判断是否满足协议
		// 要满足 OnlyFuncName && 实现 Plugin 接口
		if v, err := p.Lookup(OnlyFuncName); err != nil {
			fmt.Println("loadPlugin err ", err)
			return err
		} else if _, ok := v.(Plugin); !ok {
			fmt.Println("loadPlugin err ", fmt.Sprintf("path:%s 没有实现 %s 接口", filepath.Base(fPath), OnlyFuncName))
			return errors.New("没有实现指定接口")
		} else {

		}
		fmt.Println("loadPlugin add ", filepath.Base(fPath))
		ManagementPlugin.SetPlugin(filepath.Base(fPath), p)
	}
	return nil
}