gpt4 book ai didi

python - 将 Cython 中的 C 结构包装/转换为 Python 类

转载 作者:太空狗 更新时间:2023-10-30 02:45:43 25 4
gpt4 key购买 nike

我刚刚开始熟悉 Cython,尝试将一些结构从 C 库包装到 Python 方法和类中。我真正不明白的是如何从(初始化的)C 结构转换为相应的 Python 类。我在这里缺少什么:

C 头文件中的一个片段:

struct test_struct {
int _something;
complex_struct* _another;
};
typedef struct test_struct test;

test *test_new(void);
int some_method(test **n, int irrelevant);

我的 .pxd 中的相应片段:

cdef struct test_struct:
pass
ctypedef test_struct test

test* test_new()
int some_method(test **n, int irrelevant)

我的.pyx:

def do_something(int irrelevant):
cdef test* t = test_new()
ret = some_method(&t, irrelevant)

# Here comes the problem...
return <Test?>t

cdef class Test:
cdef test* _t

# cinit here and some methods here. No members except _t

返回语句之前的一切都正常。我在 ret 等中得到了正确的值。但是 return 语句中的转换似乎不正确或缺少更多信息。发出 t = do_something(42) Python 段错误时。

段错误本身没有任何帮助:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a9e74b in internal_print () from /usr/lib/libpython2.7.so.1.0
(gdb) bt
#0 0x00007ffff7a9e74b in internal_print () from /usr/lib/libpython2.7.so.1.0
#1 0x00007ffff7a81adb in PyFile_WriteObject () from /usr/lib/libpython2.7.so.1.0
#2 0x00007ffff7b19acb in sys_displayhook () from /usr/lib/libpython2.7.so.1.0
#3 0x00007ffff7a64c23 in PyObject_Call () from /usr/lib/libpython2.7.so.1.0
#4 0x00007ffff7af2ff7 in PyEval_CallObjectWithKeywords () from /usr/lib/libpython2.7.so.1.0
#5 0x00007ffff7af6f3b in PyEval_EvalFrameEx () from /usr/lib/libpython2.7.so.1.0
#6 0x00007ffff7af91b0 in PyEval_EvalCodeEx () from /usr/lib/libpython2.7.so.1.0
#7 0x00007ffff7af92b2 in PyEval_EvalCode () from /usr/lib/libpython2.7.so.1.0
#8 0x00007ffff7b11f9f in run_mod () from /usr/lib/libpython2.7.so.1.0
#9 0x00007ffff7b13ec0 in PyRun_InteractiveOneFlags () from /usr/lib/libpython2.7.so.1.0
#10 0x00007ffff7b140ae in PyRun_InteractiveLoopFlags () from /usr/lib/libpython2.7.so.1.0
#11 0x00007ffff7b1470e in PyRun_AnyFileExFlags () from /usr/lib/libpython2.7.so.1.0
#12 0x00007ffff7b24bcf in Py_Main () from /usr/lib/libpython2.7.so.1.0
#13 0x00007ffff746f000 in __libc_start_main () from /usr/lib/libc.so.6
#14 0x000000000040073e in _start ()

如您所见,do_something 方法应该返回一个 Test 类型的 Python 对象。我需要添加什么才能使转换成功?我是否需要手动将结构映射到 Python 类?我可以使用一些 Cython 魔法吗?

最佳答案

您需要将 Test 变成 C 类型的实际包装器。但是您也不能将 C 参数传递给 Python 函数(例如构造函数)。所以你也需要一个工厂函数。这是一个例子:

cdef class Test:
cdef test* _t

def __cinit__(self):
self._t = NULL

def _setup(self, test* t):
self._t = t
return self

property something:
def __get__(self):
return self._t._something
def __set__(self, int val):
self._t._something = val

cdef Test_create(test* t):
return Test()._setup(t)

然后在 do_something() 中:

return Test_create(t)

关于python - 将 Cython 中的 C 结构包装/转换为 Python 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23545875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com