2016-08-31 5 views
1

アイデアは関数からの "出力"のようにライブラリから配列を変更できるようにすることです。 例:Numpy PyArray *をFFI経由で渡す方法

ffi.cdef(""" 
    //Reads data from a file, and store in the numpy array 
    void read_image(PyArray* arr); 
""") 

C = ffi.dlopen('libimage.so') 
image = np.array([], dtype=np.float32) 
C.read_image(image) 
assert image.ndim == 2 

答えて

0

あなたはCFFI経由PyXxx CPythonの固有の構造体を渡すことはできません:あなたは、標準のCデータを渡す必要があります。通常、私はあなたが標準のCインタフェースを使用してCDEF() 'EDの機能を設計する必要があると答えるだろう、例えばのようなもの:

ffi.cdef(""" 
    struct myimage_t { 
     int width, height; 
     float *data; 
    }; 
    int read_image(struct myimage_t *output); // fill in '*output' 
    void free_image(struct myimage_t *img); // free output->data 
""") 

myimage = ffi.new("struct myimage_t *") 
if lib.read_image(myimage) < 0: 
    raise IOError 
... 
lib.free_image(myimage) 

は、その後、あなたはどこかで、手動でnumpyの配列にmyimageを変換する必要があります上記の "..."コード。

もう1つの選択肢は、Pythonコールバックを使用することです。コールバックは、numpy配列をspecに従って作成し、C標準のfloat *ポインタを返します。 numpy配列自体は、コールバックのどこかに保存されます。あなたはPythonのグローバルとして保存するか、Cで渡す "ハンドル"をもっときれいに使うことができます.ABIではなくAPIバージョンが必要です。 、

興味深い
from _example_cffi import ffi, lib 

class Context: 
    pass 

@ffi.def_extern() 
def alloc_2d_numpy_array(handle, w, h): 
    context = ffi.from_handle(handle) 
    context.image = np.ndarray([w, h], dtype=np.float32) 
    return ffi.cast("float *", ffi.from_buffer(context.image)) 

context = Context() 
lib.read_image(ffi.new_handle(context)) 
image = context.image 
+0

お返事に感謝:

ファイルexample.pyで
ffi.cdef(""" extern "Python" float *alloc_2d_numpy_array(void *handle, int w, int h); void read_image(void *handle); """) ffi.set_source("_example_cffi", """ void read_image(void *handle) { // the C code that eventually invokes float *p = alloc_2d_numpy_array(handle, w, h); // and then fill the data at 'p' } """) ffi.compile(verbose=True) 

:_example_build.pyで。私たちはこれを行うことができないのは残念です...私たちはnumpyの配列C APIへのアクセスを失います。トーチでは、FFIを使用して行列オブジェクトに簡単に直接アクセスでき、多くの手助けをします。 –

+0

あなたのx86実行可能ファイルがARMスマートフォンでこれ以上動作しないのは悲しいことです。 CPython C APIを使用してPyObjectsを操作するコードをお持ちの場合、それはcffiでは動作しません。これはcffiの設計目標の一部です。私の答えは、cffiの手法を使って同じ結果を得る方法の例を示しています--- Pythonオブジェクトにアクセスする必要があるときはいつでもPythonでコールバックを書いています。 –

関連する問題