【问题标题】:How to create c_void_p PyObject from C++, pass it to Python and retrieve it back to C++如何从 C++ 创建 c_void_p PyObject,将其传递给 Python 并将其检索回 C++
【发布时间】:2017-02-02 22:58:44
【问题描述】:

我需要将用 C++ 创建的 ArrayFire 数组共享给 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。基本数据类型)说 c_void_p 的 Python 类型是 int 或 None。显然在我的情况下它是无

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

谢谢!

【问题讨论】:

  • 很好奇。您没有使用 Python 包装器进行 arrayfire 的任何原因?
  • 我正在使用它。但是,如果您需要将应用程序中创建的 af::array 共享传递给 arrayfire python 绑定类型 Array,那么您将需要这个技巧。传递 af_array ref 的好处是,如果您使用 CUDA 后端,内存将保留在 GPU 中,您不会因复制数据而产生开销。

标签: python c++ arrayfire


【解决方案1】:

我解决了。

可以从 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;
}

【讨论】:

    猜你喜欢
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2012-11-08
    • 1970-01-01
    相关资源
    最近更新 更多