我正在尝试向Python公开C ++类和方法。因此,我选择使用Cython来包装两者。 C ++代码是catkin软件包的一部分,因此我研究了如何在catkin_make
内集成Cython编译的方法。
在我的虚拟示例中,有一个C ++类A
和一个工厂方法get_a()
,该方法返回一个shared_ptr<A>
。在Cython端,我创建了一对文件example_a.pxd
和example_a.pyx
,它们将C ++类A
包装到PyA
中,并将c_example_a_factory.pxd
和example_a_factory.pyx
包装起来将C ++方法get_a()
转换为同名的Cython方法。我同时将import
和cimport
类PyA
从example_a
模块扩展到example_a_factory
,并且编译良好。但是,当我尝试从python导入example_a_factory
时,出现错误:
ImportError: No module named example_a
我发现了几个回购,这些回购试图完成与构建过程有关的所需工作,并且遵循以下示例:ros_cython_example,cython_catkin_example,cython_cmake_example
您可以在this repo中找到我的示例代码,以及有关如何运行它的说明。为了便于参考,我也在这里发布了Cython文件:
example_a.pxd
from libcpp.memory cimport shared_ptr
cdef extern from "catkin_cython_example/example_a.hpp" namespace "example_a":
cdef cppclass A:
int get() const
cdef class PyA:
cdef shared_ptr[A] c_a # Hold a C++ instance which we're wrapping
@staticmethod
cdef inline create(shared_ptr[A] c_a):
cdef PyA py_a = PyA()
py_a.c_a = c_a
return py_a
example_a.pyx
from cython.operator cimport dereference as d
cdef class PyA:
def get():
cdef int v = d(self.c_a).get()
return v
c_example_a_factory.pxd
from libcpp.memory cimport shared_ptr
from example_a cimport A
cdef extern from "catkin_cython_example/example_a_factory.hpp" namespace "example_a_factory":
shared_ptr[A] get_a(int val) except +
example_a_factory.pyx
from libcpp.memory cimport shared_ptr
cimport c_example_a_factory
from example_a cimport A, PyA
from example_a import PyA
def get_a(val):
cdef shared_ptr[A] c_a = c_example_a_factory.get_a(val)
return PyA.create(c_a)
我测试了将所有内容放入一个模块中,并且代码可以正常工作,但是我宁愿使用单独的模块来简化可维护性和逻辑解耦。感谢所有的帮助!