2013-08-05 2 views
10

Ich möchte ein numpy Array Typ Bool in C++ verwenden, indem Sie den Zeiger über Cython übergeben. Ich weiß bereits, wie man es mit anderen Datentypen wie uint8 macht. Auf die gleiche Weise mit Boolean funktioniert es nicht. Ich bin in der Lage zu kompilieren, aber es gibt die folgende Ausnahme während der Laufzeit:Übergeben eines numpy Zeigers (dtype = np.bool) an C++

Traceback (most recent call last): 
    File "test.py", line 15, in <module> 
    c = r.count(b, 4) 
    File "rect.pyx", line 41, in rect.PyRectangle.count (rect.cpp:1865) 
    def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size): 
ValueError: Does not understand character buffer dtype format string ('?') 

Hier ist mein C++ Methode:

void Rectangle::count(bool * array, int size) 
{ 
    for (int i = 0; i < size; i++){ 
     std::cout << array[i] << std::endl; 
    } 
} 

Die Cython Datei:

# distutils: language = c++ 
# distutils: sources = Rectangle.cpp 

import numpy as np 
cimport numpy as np 

from libcpp cimport bool 

cdef extern from "Rectangle.h" namespace "shapes": 
    cdef cppclass Rectangle: 
     Rectangle(int, int, int, int) except + 
     int x0, y0, x1, y1 
     void count(bool*, int) 

cdef class PyRectangle: 
    cdef Rectangle *thisptr  # hold a C++ instance which we're wrapping 
    def __cinit__(self, int x0, int y0, int x1, int y1): 
     self.thisptr = new Rectangle(x0, y0, x1, y1) 
    def __dealloc__(self): 
     del self.thisptr 

    def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size): 
     self.thisptr.count(&array[0], size) 

Und hier der Python-Skript das ruft die Methode auf und erzeugt den Fehler:

import numpy as np 
import rect 

b = np.array([True, False, False, True]) 
c = r.count(b, 4) 

Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen. Vielen Dank!

Antwort

9

Es sieht aus wie das Problem mit der Array-Typ-Deklaration ist. Gemäß der Dokumentation unter https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html werden boolesche Arrays noch nicht unterstützt, aber Sie können sie verwenden, indem Sie sie als Arrays von vorzeichenlosen 8-Bit-Ganzzahlen darstellen. Hier ist ein einfaches Beispiel, das die Summe eines 1D-Array aus Boolesche Werte (die gleiche wie die sum() Methode würde für einen boolean NumPy Array)

from numpy cimport ndarray as ar 
cimport numpy as np 
cimport cython 

@cython.boundscheck(False) 
@cython.wraparound(False) 
def cysum(ar[np.uint8_t,cast=True] A): 
    cdef int i, n=A.size, tot=0 
    for i in xrange(n): 
     tot += A[i] 
    return tot 

In Ihrem C++ Code, je nachdem, was Sie tun, nimmt man Vielleicht musst du den Zeiger wieder auf einen Booler setzen, da bin ich mir nicht sicher.

Edit: Hier ist ein Beispiel dafür, wie der Zeiger in Cython zu werfen, was tun soll, was Sie wollen. Ich musste immer noch das Array als unsigned 8-Bit-Integer eingeben, aber ich warf dann den Zeiger zurück in eine bool.

from numpy cimport ndarray as ar 
cimport numpy as np 
from libcpp cimport bool 
cimport cython 

def cysum(ar[np.uint8_t,cast=True] A): 
    cdef int i, n=A.size, tot=0 
    cdef bool *bptr 
    bptr = <bool*> &A[0] 
    for i in xrange(n): 
     tot += bptr[i] 
    return tot 

Wenn Sie das Array in als Zeiger übergeben möchten, können Sie einfach verwenden Sie die folgende Funktion in Ihrer Cython Datei:

cdef bool* arptr(np.uint8_t* uintptr): 
    cdef bool *bptr 
    bptr = <bool*> uintptr 
    return bptr 

die als

genannt werden kann
arptr(&A[0])