如何从C++创建c_void_p PyObject,将其传递给Python并将其检索回C++

How to create c_void_p PyObject from C++, pass it to Python and retrieve it back to C++

本文关键字:C++ Python 检索 PyObject 创建 void      更新时间:2023-10-16

我需要共享一个 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失败与类"类型错误":需要一个整数。

ctypes doc (16.16.1.4.基本数据类型)表示c_void_p的 Python 类型是 int 或 None。显然在我的情况下是无

如何使用 C API 将c_void_p转换为 python?

谢谢!

我解决了。

可以从 value 属性中读取 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;
}