我有一个简单的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类型的参数,但从Vec3
到py_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})"