- 字符串传递
字符串在从Python传给Golang的时候,跟传递给C是一样的,需要用ctypes.cast()将字符串末尾添上终止符保护起来
buffer = ctypes.create_string_buffer("A String".encode("utf-8"))
string_c_array = ctypes.cast(ctypes.pointer(buffer), ctypes.c_char_p)
在对应的Golang代码中,函数的入参应当是 dataString *C.char这样子的,但是这样还不能直接使用,需要在接收之后进行一次转换
goString := C.GoString(dataString)
fmt.Printf("go string = %s\n", goString)
2. 数字传递
传递int是最简单的,Python里的int就可以直接使用,对应Golang代码中,函数的入参应当是`num C.int`,可以直接使用,不需要做什么转换
3. 字符串数组传递
Python代码中有一个字符串,例如:item_ids = [“Item1”, “Item2”, “Item3”],想要传给Golang函数,需要用两个参数,一个是数组的指针,一个是数组的长度,对应的argtypes分别是ctypes.POINTER(ctypes.c_char_p)和ctypes.c_int,可以简单的理解c_char_p就是string类型即可。
一个简单的样例如下:
item_ids = ["Item1", "Item2", "Item3"]
item_id_array = np.array(item_ids, dtype=np.str_)
item_id_c_array = (ctypes.c_char_p * len(item_id_array))()
for i, item_id in enumerate(item_id_array):
buffer = ctypes.create_string_buffer(item_id.encode("utf-8"))
item_id_c_array[i] = ctypes.cast(ctypes.pointer(buffer), ctypes.c_char_p)
item_id_size = len(item_ids)
在Golang函数中,使用两个参数接收,分别是ids **C.char, size C.int对应Python中的item_id_c_array和item_id_size,在Golang中使用的时候有一点细节需要注意
stringPointers := (*[1<<30 - 1]*C.char)(unsafe.Pointer(ids))[:size:size]
for _, str := range stringPointers {
fmt.Println(C.GoString(str))
}
这样便可以取出来Python传过来的数组内容了。
4. protobuf超大结构体的传递
直接把protobuf的对象给序列化了,变成字符串传递,在Python中
examples_proto = examples.SerializeToString()
在Golang中使用方法是:
var example pb.Example
err := proto.Unmarshal([]byte(C.GoString(examplesIn)), &example)
5. 把Golang的结构体传给Python
说完了Python传给Golang,在Golang代码计算好了之后,也需要把结果返回给Python
一个简单的方法就是,在Golang里面给转成json字符串,再在Python中解析一下即可
jsonObj, err := json.Marshal(dataObj)
if err != nil {
fmt.Errorf("Json Marshal DataObject Failed with error %s\n", err.Error())
panic(err)
}
return C.CString(string(jsonObj))
6. 终极优雅方案

链接:https://juejin.cn/post/7301281320667316259
(版权归原作者所有,侵删)
本文链接:https://www.yunweipai.com/44371.html
网友评论comments