2017-02-02 4 views
3

C++でPythonに作成するArrayFire配列を共有する必要があります。それはOK作品:私のPythonスクリプトは、C++の配列に私はARR属性を読んで、戻って私のポインタを取得し、それを割り当てる必要がありArrayFire配列を返す場合C++からc_void_p PyObjectを作成し、それをPythonに渡してC++に戻す方法

PyObject* arrayToPyObject(const af::array& arr) 
{ 
    // Create arrayfire array and set 
    PyObject* afArray = createObject("arrayfire", "Array"); 

    PyObject* ctypes_mod = PyImport_ImportModule("ctypes"); 
    PyObject* c_void_p = PyObject_GetAttrString(ctypes_mod, "c_void_p"); 
    PyObject* p = PyObject_CallFunction(c_void_p, "O", PyLong_FromVoidPtr(arr.get())); 

    if (PyObject_SetAttr(afArray, PyUnicode_FromString("arr"), p) == 0) 
    { 
     return afArray; 
    } 
    else 
    { 
     Py_XDECREF(afArray); 
     return nullptr; 
    } 
} 

は今ここに

af::array pyObjectToArray(PyObject* obj) 
{ 
    af::array tmp; 
    PyObject* arr = PyObject_GetAttr(obj, PyUnicode_FromString("arr")); 
    if (arr) 
    { 
     af_array ref = (af_array)(PyLong_AsVoidPtr(arr)); 

     if (ref) 
     { 
      tmp.set(ref); 
     } 
    } 

    return tmp; 
} 

発行していることですPyLong_AsVoidPtr failswithクラス 'TypeError':整数が必要です。

ctypes doc(16.16.1.4。基本データ型)は、c_void_pのPython型がintまたはNoneのいずれかであることを示します。明らかにそれは私の場合ではありません

C APIを使用してc_void_pをPythonに変換するにはどうすればよいですか?

ありがとうございます!

+0

好奇心。あなたがarrayfire用のPythonラッパーを使用していない理由は何ですか? –

+0

私はそれを使用しています。しかし、アプリケーションで作成したaf :: arrayをarrayfire pythonバインディング型Arrayに渡す必要がある場合は、そのトリックが必要です。 af_array refを渡すことの良い点は、CUDAバックエンドを使用している場合、メモリがGPU内にとどまり、データのコピーにオーバーヘッドが発生しないということです。 –

答えて

2

私はそれを解決しました。

属性からctypesタイプのオブジェクト値を読み取ることができます。

af::array pyObjectToArray(PyObject* obj) 
{ 
    af::array tmp; 
    PyObject* arr = PyObject_GetAttr(obj, PyUnicode_FromString("arr")); // <-- c_void_p object 
    PyObject* p = PyObject_GetAttr(arr, PyUnicode_FromString("value") // <-- int value 

    if (arr) 
    { 
     af_array ref = (af_array)(PyLong_AsVoidPtr(p)); 

     if (ref) 
     { 
      tmp.set(ref); 
     } 
    } 

    return tmp; 
} 
関連する問題