嵌入 Python 时共享数组的最简单方法

Posted

技术标签:

【中文标题】嵌入 Python 时共享数组的最简单方法【英文标题】:Simplest way to share an array when embedding Python 【发布时间】:2015-12-28 08:56:40 【问题描述】:

我正在用 C++ 编写一个模拟程序,并决定将 embedding it 的一些数组的初始化委托给 Python 到我的应用程序中,并使用一些 Python 函数来生成初始数据。

由于我的 2D/3D 数组是由 C++ 部分分配和管理的,因此我需要将它们传递给 Python。最好的方法可能是buffer protocol。我可以用 C++ 编写一个 Python 类,它实现了缓冲区协议,并为我在 C++ 中的存储创建了一个缓冲区对象。

现在,我想避免过度设计此过程。事实上,我只需要将一个指针、一个大小和步幅的元组传递给 Python 函数。

因此,问题是:将此信息传递给 Python 例程的最简单方法是什么,然后 Python 例程可以使用它(可能与 Numpy 一起使用)来初始化指向的存储?

举个例子说明我需要做什么,我想从 C++ 调用的 Python 函数是:

def init_field(field, X, Y):
    field[:, :] = np.sqrt(X) + np.tanh(Y)

其中XY 是由Python 创建并由C++ 应用程序借用的numpy 数组,field 正是这个由C++ 管理的二维数组。我当然可以用一个或多个参数替换field,这些参数携带有关指针、大小和步幅的信息,并构造numpy数组。我该怎么做?

【问题讨论】:

Python 存在一个boost library。你调查过吗? (请注意,我没有,我只是好奇你是否有,因为你正在寻找一个简单的集成。) 是的,我知道那个库,但它似乎对我的情况没有直接帮助。困难的不是真正与 Python 交互,而是让它理解我拥有的指针和数据结构。有一个boost::python version of the numpy C interface,但我不知道它的维护和面向未来的程度如何。我想避免过多的依赖,因为我将部署此代码的系统不是很简单。 【参考方案1】:

使用PyArray_SimpleNewFromData 并不难。使用它可能会导致如下代码:

void use_array(float* ptr, int width, int height)

    PyObject *pFunc = pyFunction("python_function_name");
    if (pFunc == 0)
        return;
    PyObject *pArgs = PyTuple_New(1);
    npy_intp dims[2];
    dims[1] = width;
    dims[0] = height;
    PyTuple_SetItem(pArgs, 0, PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, ptr));
    PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
    Py_DECREF(pArgs);
    if (pValue != NULL) 
        Py_DECREF(pValue);
    
    else 
    
        PyErr_Print();
        fprintf(stderr,"Call failed\n");
        return;
    
    Py_DECREF(pFunc);

在设置嵌入式 Python 环境时,您应该调用import_array(),如http://docs.scipy.org/doc/numpy-1.10.0/reference/c-api.array.html#miscellaneous 中所述

【讨论】:

Spiros,PyArray_SimpleNewFromData 在 .../Python27/Lib/site-packages/numpy/core/include/numpy/ndarrayobject.h 中的定义是 #define PyArray_SimpleNewFromData(nd, dims, typenum, data) PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, data, 0, NPY_ARRAY_CARRAY, NULL)。这里 data 之前的 NULL 可以有指向 strides 的指针。 这里是a link 到相关的 NumPy 的 C-API 文档。其中一项功能肯定能满足您的需求。 在使用 NumPy 的 C API 时没有明显原因的段错误通常是由于没有调用 import_array()。没有看到你的完整代码很难判断,但this link 应该会有所帮助。 我的代码在更大的框架中运行或多或少没有改变,这在这里很难重现。 Jaime 上面指出的对 import_array 的调用是必不可少的。 感谢您的澄清,现在一切正常。我不确定 inport_array 函数调用,因为我嵌入了 numpy,而不是扩展它,但我发现我仍然需要它。

以上是关于嵌入 Python 时共享数组的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

python3 - 使用脚本从父级到子级共享变量的最简单方法

配置嵌入式 MongoDB 的最简单方法

从 cargo-maven2-plugin 以嵌入式模式启动 tomcat 的最简单方法是啥?

使用带有 Swing 的鼠标绘制(单色)数组的最简单方法是啥?

在项目之间共享 React 组件的最简单方法是啥? [关闭]

提供 undetermined-lifespan bool 在线程之间共享的最简单方法是啥?