在 Python 3.x 代码中暴露 C 字符串而不复制
我有一个用Cython写的库,它封装了一个C语言库,我把一些C字符串暴露给Python代码。这些字符串很大,而且是静态的(不能释放内存),所以直接把它们转换成Python字符串(这会复制一份)就不行了——我会遇到内存不足的错误。
目前我已经在Python 2.x上用旧的缓冲区API搞定了这段代码,基本上是这样的:
def get_foo():
return PyBuffer_FromMemory(c_foo_ptr,c_foo_len)
这在Python 2.x上运行得很好,但在3.x中旧的缓冲区API已经不再使用了,我不知道该怎么用新的API来实现同样的功能。
我看到有PyMemoryView_FromBuffer和PyBuffer_FillInfo这两个函数,结合起来应该能实现相同的效果,但PyBuffer_FillInfo需要一个我没有的对象(它只是一个模块级的函数),我尝试创建一个虚拟对象并传递给它,结果却导致了段错误,所以我猜这个对象应该以某种方式支持缓冲区……但是这个文档在哪里呢?
通过对内存视图的实验,我发现它们看起来和行为都不像字符串(或字节),所以我要么得重写所有的Python代码,要么想办法重新创建那种功能。
我是不是漏掉了什么?在Python 3中有没有简单的方法来替代PyBuffer_FromMemory?
注意:我在使用Cython,但这都是原生的C API内容,所以你可以不涉及Cython来回答。
2 个回答
0
听起来你应该创建一个自己的自定义类型,并在tp_as_sequence
中实现一些方法(可能还需要在tp_as_buffer
中实现)。
1
根据这个讨论,PyBuffer_FillInfo的第二个参数是可选的。你可以用NULL代替它吗?如果不行的话,你可以自己创建一个PyBuffer实例,然后填充相应的字段。