Cython包装返回类类型的c++类方法



我有一个简单的C++Vec3类,但我很难弄清楚如何用Cython包装某些类方法。以下是文件:

vec3.h:

#ifndef VEC3_H
#define VEC3_H
struct Vec3 {
float x, y, z;
Vec3(float x, float y, float z);
Vec3 cross(Vec3 other);
};
#endif

vec3.cpp:

#include "vec3.h"
Vec3::Vec3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vec3 Vec3::cross(Vec3 other) {
return Vec3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);
}

vec3.pyx:

# cython: language_level=3
# distutils: language=c++
cdef extern from "vec3.h":
cdef cppclass Vec3:
float x, y, z
Vec3(float x, float y, float z) except +
Vec3 cross(Vec3 other)
cdef class py_Vec3:
cdef Vec3 *thisptr
def __cinit__(self, x, y, z):
self.thisptr = new Vec3(x, y, z)
# ...
cpdef cross(self, Vec3 other):
return self.thisptr.cross(other)

我首先使用编译C++代码

g++ -c vec3.cpp -o vec3.o
ar rcs vec3.a vec3.o

然后运行以下setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
vec3= Extension(
name="vec3", sources=["vec3.pyx"], libraries=["linalg"], language="c++"
)
setup(name="vec3-test", ext_modules=cythonize([vec3]))

但我从cross方法中得到以下错误:

Cannot convert 'Vec3f' to Python object

有合适的方法吗?

您在vec3.cpp中有一个打字错误

return Vec3f(...);

移除CCD_ 3。它不将Vec3f识别为类

因为Vec3是cpp类型,py_Vec3是python类型,它们不能由cython自动转换。在cpdef功能中

cpdef cross(self, Vec3 other):
return self.thisptr.cross(other)

生成的python包装器版本需要一个python类型的参数,但从Vec3py_Vec3的转换失败,返回值也失败。

你必须手动进行转换。尝试以下修改版本:

cdef class py_Vec3:
cdef Vec3 *thisptr

def __cinit__(self, x, y, z):
self.thisptr = new Vec3(x, y, z)

cdef py_Vec3 from_vec3(self, Vec3 v):
return py_Vec3(v.x, v.y, v.z)
cpdef py_Vec3 cross(self, py_Vec3 other):
return self.from_vec3(self.thisptr.cross(other.thisptr[0]))

def __dealloc__(self):
del self.thisptr

def __repr__(self):
return f"py_Vec3({self.thisptr.x}, {self.thisptr.y}, {self.thisptr.z})"

最新更新