2013-08-05 80 views
10

Tôi muốn sử dụng một mảng kiểu bool trong C++ bằng cách chuyển con trỏ qua Cython. Tôi đã biết làm thế nào để làm điều đó với các kiểu dữ liệu khác như uint8. Làm theo cách tương tự với boolean nó không hoạt động. Tôi có thể biên dịch nhưng có những ngoại lệ sau đây trong thời gian chạy:Truyền con trỏ dạng khối (dtype = np.bool) tới 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 ('?') 

Đây là c của tôi ++ phương pháp:

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

File Cython:

# 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) 

Và đây kịch bản python gọi phương thức và tạo lỗi:

import numpy as np 
import rect 

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

Vui lòng cho tôi biết nếu bạn cần thêm thông tin. Cảm ơn bạn!

Trả lời

9

Dường như vấn đề là với khai báo loại mảng. Theo tài liệu tại https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html các boolean arays chưa được hỗ trợ, nhưng bạn có thể sử dụng chúng bằng cách truyền chúng thành các mảng của các số nguyên 8 bit chưa ký. Dưới đây là một ví dụ đơn giản mà sẽ đưa tổng của một mảng 1D của các giá trị boolean (giống như các phương pháp sum() sẽ cho một mảng NumPy boolean)

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 

Trong C++ mã của bạn, tùy thuộc vào những gì bạn đang làm, bạn có thể cần phải đưa con trỏ trở lại một bool, tôi không chắc chắn về điều đó.

Chỉnh sửa: dưới đây là ví dụ về cách truyền con trỏ trong Cython, nên thực hiện những gì bạn muốn. Tôi vẫn phải gõ mảng như một số nguyên 8 bit chưa ký, nhưng sau đó tôi đưa con trỏ trở lại vào một 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 

Nếu bạn muốn vượt qua mảng trong như một con trỏ, bạn chỉ có thể sử dụng chức năng sau đây trong tập tin Cython của bạn:

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

Mà có thể được gọi là

arptr(&A[0]) 
Các vấn đề liên quan