'CppObject' no es un identificador de tipo - Cython compilar error en el uso de otra clase CPP como un argumento
Estoy tratando de hacer una biblioteca mínima C++ para usar con un proyecto Cython, pero estoy corriendo en problemas compilando una clase C++ en el mismo espacio de nombres que utiliza otra clase C++ como argumento para un método. El primer error que recibo con el ejemplo mínimo es Point3d.pxd:8:30: 'Vector3d' is not a type identifier
, quejarse del archivo .pxd para Point3d. ¿Hay ejemplos de clases C++ que se refieran entre sí pero que luego se envuelven en Cython de esta manera? ¿O es mi error en la definición de la clase misma en C++?
Point3d.cpp
#include
#include "Point3d.h"
#include "Vector3d.h"
namespace geometry {
Point3d::Point3d() {}
Point3d::Point3d(double x, double y, double z = 0.0) {
this->x = x;
this->y = y;
this->z = z;
}
Point3d::~Point3d() {}
void Point3d::move_point(const Vector3d v) {
this->x = this->x + v.x;
this->y = this->y + v.y;
this->z = this->z + v.z;
}
}
Point3d.h
#ifndef POINT3D_H
#define POINT3D_H
#include "Vector3d.h"
namespace geometry {
class Point3d {
public:
double x, y, z;
Point3d();
Point3d(double x, double y, double z);
~Point3d();
void move_point(const Vector3d v);
};
}
#endif
Point3d.pxd
cdef extern from "Point3d.cpp":
pass
cdef extern from "Point3d.h" namespace "geometry":
cdef cppclass Point3d nogil:
double x, y, z
Point3d() except +
void move_point(const Vector3d v)
Vector3d.cpp
#include
#include "Vector3d.h"
namespace geometry {
Vector3d::Vector3d() {}
Vector3d::Vector3d(double x, double y, double z = 0.0) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3d::~Vector3d() {}
}
Vector3d.h
#ifndef VECTOR3D_H
#define VECTOR3D_H
namespace geometry {
class Vector3d {
public:
double x, y, z;
Vector3d();
Vector3d(double x, double y, double z);
~Vector3d();
};
}
#endif
Vector3d.pxd
cdef extern from "Vector3d.cpp":
pass
cdef extern from "Vector3d.h" namespace "geometry":
cdef cppclass Vector3d nogil:
double x, y, z
Vector3d() except +
Vector3d(double x, double y, double z) except +
testPoint.pxd
from libcpp.vector cimport vector
from pointTest.geometry cimport Point3d
cdef class testPoint(object):
cdef vector[Point3d] *test_pt
testPoint.pyx
# distutils: language = c++
from Vector3d cimport Vector3d
from Point3d cimport Point3d
from libc.stdlib cimport free
from libcpp.vector cimport vector
cdef class TestPoint(object):
def __cinit__(TestPoint self):
self.test_pt = new vector[Point3d]()
def __init__(TestPoint self, list pt):
# initialize vectors
self.test_pt.push_back(Point3d(pt[0],
pt[1],
pt[2]))
def __dealloc__(self):
if self.anchor_pt != NULL:
free(self.anchor_pt)
cpdef move_pt(TestPoint self):
pt = self.test_pt[0].at(0)
pt.move_pt(Vector3d(1, 1, 1))
setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
ext = Extension("testPoint",
sources=["testPoint.pyx", "Point3d.cpp", "Vector3d.cpp"],
language="c++")
setup(name="testPoint", ext_modules=cythonize(ext))
Pregunta hecha hace 3 años, 4 meses, 28 días - Por scriptsculptor52b5
2 Respuestas:
-
El error que estás viendo se debe a que Cython no puede reconocer la clase
Vector3d
cuando se define en la declaración de la clasePoint3d
en el archivo Point3d.pxd. Para solucionar este problema, necesitas proporcionar una declaración deVector3d
en el archivo Point3d.pxd antes de usarla en la definición dePoint3d
.Aquí te muestro cómo puedes modificar Point3d.pxd para incluir la declaración de
Vector3d
:python cdef extern from "Vector3d.h" namespace "geometry": cdef cppclass Vector3d nogil: double x, y, z Vector3d() except + Vector3d(double x, double y, double z) cdef extern from "Point3d.cpp": pass cdef extern from "Point3d.h" namespace "geometry": cdef cppclass Point3d nogil: double x, y, z Point3d() except + void move_point(const Vector3d v)
Con esta modificación, Cython ahora reconocerá la clase
Vector3d
al compilar el código. Recuerda también asegurarte de que las rutas de inclusión y las declaraciones de nombres de espacio coincidan en todos los archivos relacionados.Respondida el Dec 19, 2020 a las 06:35 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema radica en el orden de inclusión de los archivos de encabezado en Point3d.pxd. El archivo de encabezado de Vector3d.h debe incluirse antes que Point3d.h para que el compilador Cython sepa sobre la clase Vector3d cuando intente compilar el método move_point.
Aquí tienes el Point3d.pxd corregido:
cdef extern from "Vector3d.h" namespace "geometry": cdef cppclass Vector3d nogil: double x, y, z Vector3d() except + Vector3d(double x, double y, double z) except + cdef extern from "Point3d.h" namespace "geometry": cdef cppclass Point3d nogil: double x, y, z Point3d() except + Point3d(double x, double y, double z) except + void move_point(const Vector3d v)
Además, asegúrate de que Vector3d.h y Point3d.h se incluyen correctamente en sus respectivos archivos .cpp. Aquí tienes los archivos .cpp corregidos:
Point3d.cpp
cpp
include "Vector3d.h" include "Point3d.h" namespace geometry { Point3d::Point3d() {} Point3d::Point3d(double x, double y, double z) { this->x = x; this->y = y; this->z = z; } Point3d::~Point3d() {} void Point3d::move_point(const Vector3d v) { this->x = this->x + v.x; this->y = this->y + v.y; this->z = this->z + v.z; } }Vector3d.cpp
cpp
include "Vector3d.h" namespace geometry { Vector3d::Vector3d() {} Vector3d::Vector3d(double x, double y, double z) { this->x = x; this->y = y; this->z = z; } Vector3d::~Vector3d() {} }Ahora deberías poder compilar tu código Cython sin errores.
Respondida el Dec 19, 2020 a las 06:41 - por Gemini
Votos positivos: 0 | Votos negativos: 0