我试图用Cython将一些C++类和函数封装到Python中。 到目前为止,我已经包装了2个类,现在我想包装一个函数。在
函数的签名是
std::map<std::string, std::vector<PyObject*>> analyze(PyObject* img, LandmarkDetector::CLNF& clnf_model, LandmarkDetector::FaceModelParameters& params);
我已经成功地包装了CLNF
和FaceModelParameters
类,并且在包装{
这个函数处理PyObject*
s,因为它处理opencv,我希望能够在语言之间轻松地传递它们。我使用these functions来执行cv::Point
到python对象和python Mat到cv::Mat
之间的转换。在
这是我的pyx文件:
from libcpp.vector cimport vector
from libcpp.map cimport map
from libcpp.string cimport string
from cpython.ref cimport PyObject
from cython.operator cimport dereference as deref
cdef extern from "LandmarkDetectorModel.h" namespace "LandmarkDetector":
cdef cppclass CLNF:
CLNF(string) except +
cdef extern from "LandmarkDetectorParameters.h" namespace "LandmarkDetector":
cdef cppclass FaceModelParameters:
FaceModelParameters(vector[string] &) except +
cdef class PyCLNF:
cdef CLNF *thisptr
def __cinit__(self, arg):
self.thisptr = new CLNF(<string> arg)
cdef class PyLandmarkDetectorParameters:
cdef FaceModelParameters *thisptr
def __cinit__(self, args):
self.thisptr = new FaceModelParameters(args)
cdef extern from "FaceLandmarkVid.h":
map[string, vector[object]] analyze(object, CLNF&, FaceModelParameters&)
cdef PyAnalyze(object img, PyCLNF clnf, PyLandmarkDetectorParameters facemodel):
return analyze(img, deref(clnf.thisptr), deref(facemodel.thisptr))
但是在尝试编译它时,我得到了错误消息
^{pr2}$(指map[string, vector[object]] analyze [...]
行)
不幸的是,这里不能使用Cython的自动
std::map
->;dict
和std::vector
->;list
转换。我认为编写这样一个转换的根本问题是Cython不知道C++在引用计数中所做的事情,所以很难可靠地得到正确的结果。在相反,您必须将向量模板化为
PyObject*
,并编写自己的转换函数。使用PyObject*
进行模板化似乎会混淆Cython,但这可以通过typedef解决:本质上,我们迭代地图,并迭代其中的向量,将
PyObject*
转换为<object>
。我已经假设了这里的引用计数——我假设C++代码永远不会减少向量中^ {< CD9}}s的引用计数(因此,您需要自己减少它来考虑向量的破坏)。第二个假设是PyObject*
都不是空的。在(这是在Cython编译的测试,但我无法测试它是用C++编译还是正确运行)。在
编辑:我意识到我在参考计数时犯了一个小错误,现在该纠正了。在
相关问题 更多 >
编程相关推荐