go插件化

什么是go plugin

Golang是静态编译型语言,在编译时就将所有引用的包(库)全部加载打包到最终的可执行程序(或库文件)中,因此并不能在运行时动态加载其他共享库。Go Plugin提供了这样一种方式,能够让你在运行时动态加载外部功能。

为什么用go plugin

  • 可插拔
  • 动态加载的需要
  • 独立开发

实例

go plugin示例

  1. 创建一个插件方法aplugin.go:
package main
func Add(x, y int) int {
	return x+y
}
func Subtract(x, y int) int {
	return x-y
}

构建插件aplugin.so
go build -buildmode=plugin -o aplugin.so aplugin.go
  1. 调用插件 创建一个test.go
package main

import (
	"fmt"
	"plugin"
)

func main(){
	p,err := plugin.Open("")
	if err != nil {
        fmt.Println("error open plugin: ", err)
        os.Exit(-1)
    }
    add,_ : =p.Lookup("Add")
    sum := add.(func(int,int)int)(11,2)
    fmt.Println(sum)
}

cshared 示例

除了上面提到的buildmode=plugin外,还有一种用法就是 buildmode=c-shared ,使用该参数时会生成出来两个文件,一个.so文件,一个.h头文件

  1. awesome.go代码
    package main
    import "C"
    import (
    	"fmt"
    	"math"
    	"sort"
    	"sync"
    )
    var count int
    var mtx sync.Mutex
    //export Add
    func Add(a, b int) int {
    	return a + b
    }
    //export Cosine
    func Cosine(x float64) float64 {
    	return math.Cos(x)
    }
    //export Sort
    func Sort(vals []int) {
    	sort.Ints(vals)
    }
    //export Log
    func Log(msg string) int {
    	mtx.Lock()
    	defer mtx.Unlock()
    	fmt.Println(msg)
    	count++
    	return count
    }
    func main() {}
    
编译命令如下:
go build -o awesome.so -buildmode=c-shared awesome.go
  1. c语言动态链接调用
    #include <stdio.h>
    #include "awesome.h"
    int main() {
        //Call Add() - passing integer params, interger result
        GoInt a = 12;
        GoInt b = 99;
        printf("awesome.Add(12,99) = %d\n", Add(a, b));
        //Call Cosine() - passing float param, float returned
        printf("awesome.Cosine(1) = %f\n", (float)(Cosine(1.0)));
        //Call Sort() - passing an array pointer
        GoInt data[6] = {77, 12, 5, 99, 28, 23};
        GoSlice nums = {data, 6, 6};
        Sort(nums);
        printf("awesome.Sort(77,12,5,99,28,23): ");
        for (int i = 0; i < 6; i++){
            printf("%d,", ((GoInt *)nums.data)[i]);
        }
        printf("\n");
        //Call Log() - passing string value
        GoString msg = {"Hello from C!", 13};
        Log(msg);
    }

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×