13

Cython 経由でポインターを渡すことにより、C++ で bool 型の numpy 配列を使用したいと思います。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)

さらに情報が必要な場合はお知らせください。ありがとうございました!

4

1 に答える 1

12

問題は配列型の宣言にあるようです。https://cython.readthedocs.org/en/latest/src/tutorial/numpy.htmlのドキュメントによると、ブール配列はまだサポートされていませんが、符号なし 8 ビット整数の配列としてキャストすることで使用できます。これは、ブール値の 1D 配列の合計を取る簡単な例です (ブール値の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])
于 2013-08-05T14:27:06.970 に答える