web-dev-qa-db-fra.com

problème de cython: 'bool' n'est pas un identifiant de type

J'essaie désespérément d'exposer un std::vector<bool> membre de classe à une classe Python.

Voici ma classe C++:

class Test
{
  public:
    std::vector<bool> test_fail;
    std::vector<double> test_ok;
};

Alors que l'accès et la conversion de test_ok de type double (ou int, float, ..) fonctionne, il ne fonctionne pas pour bool!

Voici ma classe Cython:

cdef class pyTest:
     cdef Test* thisptr
     cdef public vector[bool] test_fail
     cdef public vector[double] test_ok

     cdef __cinit__(self):
         self.thisptr = new Test()
         self.test_fail = self.thisptr.test_fail # compiles and works if commented
         self.test_ok = self.thisptr.test_ok

     cdef __dealloc__(self):
         del self.thisptr

L'erreur que j'obtiens est:

Error compiling Cython file:
------------------------------------------------------------
...




cdef extern from *:
    ctypedef bool X 'bool'
            ^
------------------------------------------------------------

vector.from_py:37:13: 'bool' is not a type identifier

J'utilise python 2.7.6 et Cython 0.20.2 (également essayé 0.20.1).

J'ai aussi essayé avec des propriétés mais ça ne marche pas non plus.

Addendum: J'ai le from libcpp cimport bool en haut de mon fichier pyx, ainsi que l'importation de vecteur.

Qu'est-ce qui ne va pas ?? Je pense que cela pourrait être un bug. Quelqu'un sait comment contourner cela? Merci.

31
carmellose

J'ai trouvé une solution de contournement valide, même si elle n'est peut-être pas optimale.

J'ai remplacé les types de membres de la classe pytest par python listes.

La conversion est maintenant effectuée implicitement, comme décrit dans la documentation: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library

Toutes les conversions créent un nouveau conteneur et y copient les données. Les articles dans les conteneurs sont convertis automatiquement en un type correspondant, ce qui inclut la conversion récursive des conteneurs à l'intérieur des conteneurs, par ex. un vecteur C++ de cartes de chaînes.

Alors maintenant, ma classe ressemble à ceci:

cdef class pyTest:
     cdef Test* thisptr
     cdef public list test_fail #now ok
     cdef public list test_ok

     cdef __cinit__(self):
         self.thisptr = new Test()
         self.test_fail = self.thisptr.test_fail # implicit copy & conversion
         self.test_ok = self.thisptr.test_ok # implicit copy and conversion

     cdef __dealloc__(self):
         del self.thisptr
2
carmellose

Il y a un support supplémentaire C++ que vous devez faire. En haut de votre fichier .pyx, ajoutez

from libcpp cimport bool

Je jetterais un coup d'œil à l'intérieur pour trouver les autres choses dont vous pourriez avoir besoin, comme les conteneurs std :: string et STL

44
Ben

Pour définir les objets boolean dans cython, ils doivent être définis comme bint. Selon ici : le bint de l'objet "boolean int" est compilé en c int, mais contraint vers et depuis Cython en tant que booléens.

20
Dalek