python调用golang的函数

python调用golang

python调用golang脚本,中间需要通过cgo进行

  • golang部分

    • 需要先导入cgo和一些标准库

      import (
        "fmt"
        "quote/node_exporter"
        "unsafe"
            )
        /*
       #cgo CFLAGS:
       #include 
       #include 
       */
       import "C" //需要紧挨着
      
    • 暴露一些golang函数

      • 注意:
        • // 和export 必须要紧挨着
        • 如果需要传参的话,需要用c的类型
          字符串用*C.char,go的函数接受使用的时候必须要转化成go的string类型,用C.GoString进行转换,返回字符串类型时也必须要用*C.char类型 用C.CString转换
        • cgo 必须要对*C.char类型的变量进行释放,不然会引起内存泄漏,用C.free(unsafe.Pointer(restring)) 方式释放,但是不能提前释放,否则python调用的时候会出现乱码的情况
      //export必须要放在函数上方,后面接上python调用的函数名称
      
      
      
      //export get_stat_info
      def get_stat_info(quote *C.char) *C.char {
        var (
        	resString *C.char
        	res       = make(map[string]string)
        	mapString string
        )
        quoteS := C.GoString(quote)
        defer C.free(unsafe.Pointer(resString))
        stat, err := node_exporter.GetStatInfo(quoteS)
        if err != nil {
        	errF := fmt.Sprintf("couldn't get net stat info: %v", err)
        	res["code"] = "1"
        	res["content"] = errF
        	mapString = node_exporter.ProcessMap(res)
        	resString = C.CString(mapString)
        	return resString
        }
        if stat == "" {
        	errF := fmt.Sprintf("quote not exist: %v", quoteS)
        	res["code"] = "1"
        	res["content"] = errF
        	mapString = node_exporter.ProcessMap(res)
        	resString = C.CString(mapString)
        	return resString
        }
        res["code"] = "0"
        res["content"] = stat
        mapString = node_exporter.ProcessMap(res)
        resString = C.CString(mapString)
        return resString
        }
      }
      
    • 编译部分

      在写完golang脚本之后需要将脚本编译成二进制文件

      例:

      go build -buildmode=c-shared -o quote.so quote.go
      

      上面的命令会生成一个quote.so的二进制文件

  • python部分

    • python调用golang的二进制文件

      • 导入ctypes模块

        • 通过CDLL方法load二进制文件的库
        • 需要导入ctypes中的数据类型,指定函数返回的结果类型为c的char类型
        • 如果需要传入参数,需要进行转化一下,统一成utf编码
        import ctypes
        from ctypes import *
        
        quotes = ctypes.CDLL("./quote.so") 
        # c_char_p c的char类型
        get_stat_info = quotes.get_stat_info
        get_stat_info.restype = c_char_p
        quote_string = "node_disk_io_now".encode("utf-8")
        res = get_stat_info(quote_string)
        
        

你可能感兴趣的:(golang,golang,python,开发语言)