【问题标题】:Exposing a C string without copying to python 3.x code公开 C 字符串而不复制到 python 3.x 代码
【发布时间】:2011-02-16 11:33:01
【问题描述】:

我有一个用 cython 编写的库,它包装了一个 C 库,我将一些 c 字符串公开到 python 代码中。这些字符串很大,而且是静态的(不能解除分配),所以不能只从它们中创建一个 python 字符串(复制)——我会遇到 OOM 错误。

我的代码适用于当前使用旧缓冲区 API 的 python 2.x,它看起来或多或少类似于:

def get_foo():
     return PyBuffer_FromMemory(c_foo_ptr,c_foo_len)

这仅适用于 (tm) python 2.x,但旧的缓冲区 API 在 3.x 中消失了,我不知道如何使用新的。

我看到有 PyMemoryView_FromBufferPyBuffer_FillInfo 组合起来应该会做同样的事情,但是 PyBuffer_FillInfo 想要一个不存在的对象对我来说(它只是一个模块级函数),制作一个虚拟对象并传递它只会给我一个段错误,所以我猜这个对象应该以某种方式支持缓冲区......但是它记录在哪里?

除了尝试内存视图之外,它们看起来或充当字符串(或字节),所以我将不得不重写我所有的 python 代码或以某种方式重新创建该功能。

我错过了什么吗?有没有一种简单的方法来替换py3k中的PyBuffer_FromMemory?

注意:我使用的是 cython,但这是原始的 c-api 东西,所以你可以在不涉及 cython 的情况下回答。

【问题讨论】:

    标签: python api python-3.x


    【解决方案1】:

    根据this thread,PyBuffer_FillInfo 的第二个参数是可选的。你能通过 NULL 代替它吗?如果没有,您可以自己创建一个 PyBuffer 实例并填写相应的字段。

    【讨论】:

    • 抱歉有点忘记了这个问题......在 cython-users 上讨论它之后,我朝不同的方向前进 - 将数据包装在我自己的使用新缓冲区协议的对象中并模拟一些旧的-style 缓冲对象功能。我会将这个答案标记为接受,因为它是最有用的:)
    • @bdew 你能分享你的最终结果吗?我正在尝试做同样的事情,但我发现文档没有帮助,新的缓冲区 API 更重量级,到目前为止我所获得的只是内存泄漏和崩溃。顺便说一下,邮件列表链接已失效。
    【解决方案2】:

    在我看来,您应该创建自己的custom type 并酌情实现tp_as_sequence(可能还有tp_as_buffer)中的方法。

    【讨论】:

    • 您的链接指向旧式缓冲区 API 文档(适用于 python 2.7),新 API 似乎使用完全不同的插槽。但是感谢指针,如果我将其包装在一个对象中,这些可能是我需要实现的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 2019-09-27
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多