【发布时间】:2014-11-14 19:12:21
【问题描述】:
我想将带有cython 的现有c++ 库移植到Python,C++ 库使用templates。在这种情况下,它是adevs library。
问题是如何使用 Cython 将 Python 对象存储在 C++ 容器中?我知道这在某种程度上是discouraged,用于引用计数的问题,但是可以这样做吗?如果可以,怎么做?
我知道Gauthier Boaglios' answer 到similar question。但是,这显然不能解决引用计数的问题,因为我尝试了以下操作:
假设在 'cadevs.pxd' 我有以下代码:
cdef extern from "adevs/adevs_digraph.h" namespace "adevs":
cdef cppclass PortValue[VALUE, PORT]:
PortValue() except +
PortValue(PORT port, const VALUE& value) except +
PORT port
VALUE value
在'adevs.pyx'中:
from cpython.ref cimport PyObject
cimport cadevs
ctypedef PyObject* PythonObject
cdef class PortValue:
cdef cadevs.PortValue[PythonObject, PythonObject]* _c_portvalue
def __cinit__(self, object port, object value):
self._c_portvalue = new cadevs.PortValue[PythonObject, PythonObject](
<PyObject *>port, <PyObject *>value
)
def __dealloc__(self):
del self._c_portvalue
property port:
def __get__(self):
return <object>self._c_portvalue.port
property value:
def __get__(self):
return <object>self._c_portvalue.value
然后我 cythonize 并编译
$ cython --cplus -3 adevs.pyx
$ g++ -shared -pthread -fPIC -fwrapv -O2 -Wall -I/usr/include/python3.4m -I../include -lpython3.4m -o adevs.so adevs.cpp
但是在 python 或 ipython 中运行
import adevs
pv = adevs.PortValue((1,2), 3)
pv.port
pv.port
显然,当对 (1, 2) 元组的引用丢失时,Python 崩溃了。
【问题讨论】:
-
我建议使用
boost::python,它提供了比原始 python c-API 更好、更直接的 c++ 集成。 -
我强烈推荐 pybind11 pybind11.readthedocs.io/en/latest 这个库使得绑定 C++ 代码变得非常容易。
标签: c++ cython templates python c++ templates cython