我们需要从 Cython 中的一个类的方法创建一个 PyCapsule。我们设法编写了一个可以编译甚至运行没有错误的代码,但结果是错误的。
一个简单的例子在这里:https ://github.com/paugier/cython_capi/tree/master/using_cpython_pycapsule_class
胶囊由 Pythran 执行(需要使用 github 上的版本https://github.com/serge-sans-paille/pythran)。
.pyx 文件:
from cpython.pycapsule cimport PyCapsule_New
cdef int twice_func(int c):
return 2*c
cdef class Twice:
cdef public dict __pyx_capi__
def __init__(self):
self.__pyx_capi__ = self.get_capi()
cpdef get_capi(self):
return {
'twice_func': PyCapsule_New(
<void *>twice_func, 'int (int)', NULL),
'twice_cpdef': PyCapsule_New(
<void *>self.twice_cpdef, 'int (int)', NULL),
'twice_cdef': PyCapsule_New(
<void *>self.twice_cdef, 'int (int)', NULL),
'twice_static': PyCapsule_New(
<void *>self.twice_static, 'int (int)', NULL)}
cpdef int twice_cpdef(self, int c):
return 2*c
cdef int twice_cdef(self, int c):
return 2*c
@staticmethod
cdef int twice_static(int c):
return 2*c
pythran ( call_capsule_pythran.py
) 编译的文件。
# pythran export call_capsule(int(int), int)
def call_capsule(capsule, n):
r = capsule(n)
return r
再一次,它是 Pythran 的一项新功能,因此需要 github 上的版本...
和测试文件:
try:
import faulthandler
faulthandler.enable()
except ImportError:
pass
import unittest
from twice import Twice
from call_capsule_pythran import call_capsule
class TestAll(unittest.TestCase):
def setUp(self):
self.obj = Twice()
self.capi = self.obj.__pyx_capi__
def test_pythran(self):
value = 41
print('\n')
for name, capsule in self.capi.items():
print('capsule', name)
result = call_capsule(capsule, value)
if name.startswith('twice'):
if result != 2*value:
how = 'wrong'
else:
how = 'good'
print(how, f'result ({result})\n')
if __name__ == '__main__':
unittest.main()
它是越野车并给出:
capsule twice_func
good result (82)
capsule twice_cpdef
wrong result (4006664390)
capsule twice_cdef
wrong result (4006664390)
capsule twice_static
good result (82)
它表明它适用于标准函数和静态函数,但方法存在问题。
请注意,它适用于两个胶囊的事实似乎表明问题并非来自 Pythran。
编辑
在 DavidW 的评论之后,我了解到我们必须在运行时(例如在 中get_capi
)创建一个 C 函数,其签名int(int)
来自绑定方法twice_cdef
的签名,其签名实际上是int(Twice, int)
.
我不知道这是否真的不可能与 Cython 做...