使用Cython将结构从C返回到Python

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Cython将结构从C返回到Python相关的知识,希望对你有一定的参考价值。

我试图从c文件中将结构传回我的Python。假设我有一个像这样的文件pointc.c:

typedef struct Point {
    int x;
    int y;
} Point;

struct Point make_and_send_point(int x, int y);

struct Point make_and_send_point(int x, int y) {
    struct Point p = {x, y};
    return p;
}

然后我设置一个像这样的point.pyx文件:

"# distutils: language = c"
# distutils: sources = pointc.c

cdef struct Point:
    int x
    int y

cdef extern from "pointc.c":
    Point make_and_send_point(int x, int y)

def make_point(int x, int y):
    return make_and_send_point(x, y) // This won't work, but compiles without the 'return' in-front of the function call

如何将返回的结构体放入Python中?这种事情只能通过在Cython中创建一个结构并通过引用发送到void c函数来实现吗?

作为参考,我的setup.py是:

from distutils.core import setup, Extension
from Cython.Build import cythonize

setup(ext_modules = cythonize(
      "point.pyx",
      language="c"
     )
)
答案

通常,您会编写某种包含c级结构的包装类,例如:

# point.pyx
cdef extern from "pointc.c":
    ctypedef struct Point:
        int x
        int y
    Point make_and_send_point(int x, int y)

cdef class PyPoint:
    cdef Point p

    def __init__(self, x, y):
        self.p = make_and_send_point(x, y)

    @property
    def x(self):
       return self.p.x

    @property
    def y(self):
        return self.p.y

在使用中

>>> import point
>>> p = point.PyPoint(10, 10)
>>> p.x
10
另一答案

给定结构的Cython的默认行为是将它转换为Python字典,这对你来说可能已经足够了。 (这仅适用于由简单类型组成的结构)。

有几个原因导致这种情况无效。首先,您应该从头文件中执行cdef extern from,而不是源文件,否则会出现多个定义的错误(我认为这只是创建最小示例时的错误)。其次,您需要将Point的定义放在cdef extern块中:

cdef extern from "pointc.h":
    cdef struct Point:
        int x
        int y

如果你不这样做,那么Cython会为你的结构(__pyx_t_5point_Point)创建一个错误的内部名称,它与C函数签名不匹配,因此失败。

通过此更正,您将获得将结构转换为dicts的正确默认行为。 (这应该是双向的 - 你可以将dicts转换回结构)。如果这不是您想要的,请关注@ chrisb的答案

以上是关于使用Cython将结构从C返回到Python的主要内容,如果未能解决你的问题,请参考以下文章

Cython:从 C 程序调用 Python 代码

如何将 Cython 生成的模块从 python 导入 C/C++ 主文件? (用 C/C++ 编程)[关闭]

从 C++ 函数 Cython 返回包含 PyObject 的复杂对象

如何使用 Cython 向 Python 公开返回 C++ 对象的函数?

cython与python的不同都有哪些

cython和python的区别