我們還可以利用cffi
幫我們直接build module來供Python來使用
你可以在我的github repo找到這些程式碼(點我)
你可以一樣利用os.system
來call go幫忙編譯成動態程式庫,提供Python來用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import os os.system("go build -buildmode=c-shared -o libtest.dll test.go")
from cffi import FFI ffi = FFI() ffi.cdef(""" typedef long long GoInt; void printBye(); GoInt sum(GoInt p0, GoInt p1); """)
lib = ffi.dlopen("libtest.dll")
lib.printBye() lib.sum(1, 2)
|
然後就可以用cffi
載入dll來呼叫函數,不這個例子還看不出來cffi
有什麼差別
下面這個例子,可以讓你透過cffi
來使用Go的struct
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
| package main
import "C"
import ( "fmt" "math" "sort" "sync" )
var count int var mtx sync.Mutex
func Add(a, b int) int { return a + b }
func Cosine(x float64) float64 { return math.Cos(x) }
func Sort(vals []int) { sort.Ints(vals) }
func Log(msg string) int { mtx.Lock() defer mtx.Unlock() fmt.Println(msg) count++ return count }
func main() {}
|
上面是go檔案,下面是Python檔
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
| from cffi import FFI
import os os.system("go build -buildmode=c-shared -o awesome.dll awesome.go")
ffi = FFI()
ffi.cdef(""" typedef long long GoInt;
typedef struct { void* data; GoInt len; GoInt cap; } GoSlice;
typedef struct { const char *data; GoInt len; } GoString;
GoInt Add(GoInt a, GoInt b); double Cosine(double v); void Sort(GoSlice values); GoInt Log(GoString str); """)
lib = ffi.dlopen("awesome.dll")
print("awesome.Add(12,99) = %d" % lib.Add(12,99)) print("awesome.Cosine(1) = %f" % lib.Cosine(1))
data = ffi.new("GoInt[]", [74,4,122,9,12]) nums = ffi.new("GoSlice*", {'data':data, 'len':5, 'cap':5}) lib.Sort(nums[0]) print("awesome.Sort(74,4,122,9,12) = %s" % \ [ffi.cast("GoInt*", nums.data)[i] for i in range(nums.len)])
data = ffi.new("char[]", b"Hello Python!") msg = ffi.new("GoString*", {'data':data, 'len':13}) print("log id %d" % lib.Log(msg[0]))
|