我正在从Python中调用一个Go函数。该Go函数返回一个字符串,具体而言,是一个GoString
,其中字符串本身在Go的一侧分配。
问题
谁负责释放这块内存?
以下是一个非常简化的示例。
Go端:
func Create(optsEncoded string) (res string, serr string) {
opts := map[string]interface{}{}
if err := json.Unmarshal([]byte(optsEncoded), &opts); err != nil {
return "", errWithStack(err)
}
options := translateCreateOptions(opts)
result := ...
payload, err := json.Marshal(result)
if err != nil {
return "", errWithStack(err)
}
return string(payload), ""
}
Cython绑定:
cpdef object py_create(object items, bytes options):
cdef GoString opts = ...
cdef bytes message
cdef Create_return result = Create(opts)
if result.r0.n == 0:
message = result.r1.p
raise Exception("Something happened")
message = result.r0.p
# Do I need to deallocate result.r0 and result.r1?
return message.decode("utf-8")
CString
时,内存将使用与生成Go代码链接的libc
的C.malloc
进行分配。因此,当将此代码与“普通”的C代码或作为Python扩展的C代码组合时,需要做两件事情:1)编译该C代码时将链接相同的libc
- 以具有相同的malloc
和free
实现,2)您的C扩展必须有一种方法来调用未装饰的free
释放从Go侧传递的内存(而不是来自任何CPython内存管理代码的某些函数,如果有的话)。 - kostixfree
和malloc
的几个非常重要的观点。更多细节是,Python自己的分配器分别称为Py_Malloc
和Py_Free
,以避免与libc
版本混淆。在Cython代码中,使用from libc.stdlib cimport free, malloc
来使用Go通过libc使用的相同函数。 - danny