问题 将numpy指针(dtype = np.bool)传递给C ++


我想在C ++中使用一个类型为bool的numpy数组,方法是通过Cython传递它的指针。我已经知道如何使用uint8等其他数据类型。用布尔值做同样的方法它不起作用。我能够编译,但在运行时有以下异常:

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 ('?')

这是我的c ++方法:

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

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)

在这里调用方法并生成错误的python脚本:

import numpy as np
import rect

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

如果您需要更多信息,请与我们联系。谢谢!


6037
2017-08-05 12:56


起源



答案:


看起来问题在于数组类型声明。 根据文件 https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html 目前尚不支持布尔数组,但您可以将它们作为无符号八位整数数组使用。 这是一个简单的例子,它取一个布尔值数组的总和(与。相同) sum() 方法将为布尔NumPy数组)

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

在您的C ++代码中,根据您正在做的事情,您可能需要将指针强制转换为bool,我不确定。

编辑:这是一个如何在Cython中转换指针的示例,它应该做你想要的。 我仍然必须将数组键入为无符号的8位整数,但我然后将指针强制转换为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

如果要将数组作为指针传递,可以在Cython文件中使用以下函数:

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

这可以称为

arptr(&A[0])

11
2017-08-05 14:27