Как создать c_void_p PyObject из C ++, передать его в Python и получить обратно в переполнение стека

Мне нужно поделиться массивом ArrayFire, создавая в C ++ для Python. Это работает хорошо:

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;
}
}

Теперь, если мой скрипт Python возвращает массив ArrayFire, мне нужно прочитать атрибут arr, вернуть мой указатель и назначить его массиву C ++.

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 отказывает с классом ‘TypeError’: требуется целое число.

ctypes doc (16.16.1.4. Основные типы данных) говорит, что тип Python для c_void_p имеет тип int или None. Очевидно, это не None в моем случае

Как я могу преобразовать c_void_p в python, используя C API?

Спасибо!

3

Решение

Я решил это.

Значения объектов типа 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector