【发布时间】:2022-03-01 23:50:04
【问题描述】:
总结
我需要在 Python 对象中存储一个 C 结构,以便在使用 Cython 增强的其他部分中使用。我相信 PyCapsule 最适合这个目的,但我的代码结果不是我所期望的。虽然指针地址正确返回,但内存似乎已被释放。
详情
我是 Cython 的新手,我正在学习使用它来加速我的部分代码。为了提出这个问题,我简化了我的代码,并使用了 int 来代替 struct。
我根据对PyCapsule documentation的理解编写了CythonTest.pyx,并使用标准命令用setup.py编译:
python setup.py build_ext --inplace
CythonTest.pyx
#cython: language_level=3
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer
class Test:
def __init__(self):
cdef int test = 10
cdef const char *name = "test"
self.vars = PyCapsule_New(<void *>&test, name, NULL)
# Print pointer address
print("{0:x}".format(<unsigned long long>test))
def peek(self):
cdef const char *name = "test"
if not PyCapsule_IsValid(self.vars, name):
raise ValueError("invalid pointer to parameters")
cdef int *test = <int *>PyCapsule_GetPointer(self.vars, name)
print(test[0])
# Print pointer address
print("{0:x}".format(<unsigned long long>test))
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("CythonTest.pyx"))
然后,我使用以下 Python 脚本运行它。
from CythonTest import Test
test = Test()
print(test.vars)
test.peek()
控制台打印出以下内容:
cbde7ebe70
<capsule object "test" at 0x0000027516467930>
0
cbde7ebe70
似乎指针已成功存储在 PyCapsule 中,并按照相同地址的指示进行检索。但是,地址中现在存储的是 0 而不是 10。我知道使用 int 可能会导致它被垃圾收集并改变了问题的性质,但是在使用 PyMem_Malloc 时也会出现同样的问题。
那么问题来了:PyCapsule的正确使用方法是什么?
环境
- 编译器:Visual Studio Express 2015
- 赛通:0.26
- 操作系统:Windows 10(64 位)
- Python:3.5.3
- Spyder (IDE):3.2.3
【问题讨论】:
标签: c python-3.x cython