PyArray_SimpleNewFromData示例

9
我知道这个问题已经被回答了很多次,我也阅读了文档,但仍然不清楚它是如何工作的。也就是说,我不明白它的参数是如何填充值的。示例没有很清楚地解释它(或者可能是我自己理解能力有限)。请问有人可以帮我理解这个函数的参数是如何填充的吗?它们应该具有什么值?
我需要在不重新分配内存的情况下从C++传递一个向量到Python。
非常感谢任何帮助。我已经卡在这个问题上很多天了。
我正在实现的代码:
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pArgs,*pXVec,*c, *xarr1;
int i;
float fArray[5] = {0,1,2,3,4};
//float *p = &fArray[0] ;
npy_intp m = 5;
//void* PyArray_GetPtr(PyArrayObject* aobj, npy_intp* ind)¶


// Initialize the Python Interpreter
Py_Initialize();
PySys_SetArgv(argc, argv); 
// Build the name object
pName = PyString_FromString(argv[1]);

// Load the module object
pModule = PyImport_Import(pName);
printf("check0\n");
// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);
printf("check1\n");
// pFunc is also a borrowed reference 
pFunc = PyDict_GetItemString(pDict, argv[2]);
printf("check2\n");
//    if (PyCallable_Check(pFunc)) 
//    {
// Prepare the argument list for the call
//xarr1 = PyFloat_FromDouble(xarr[1]);
    printf("check3\n");
c = PyArray_SimpleNewFromData(1,&m,NPY_FLOAT,(void *)fArray);
printf("check3\n");
    pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs,0, c);    

    pValue = PyObject_CallObject(pFunc, pArgs);

    if (pArgs != NULL)
    {
        Py_DECREF(pArgs);
    }

//}
//   else 
//    {
//        PyErr_Print();
//    }

// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);

// Finish the Python Interpreter
Py_Finalize();

return 0;
}
2个回答

8

这个函数

 PyObject *
    PyArray_SimpleNewFromData(
        int nd, 
        npy_intp* dims, 
        int typenum, 
         void* data)
  • 最后一个参数 (data) 是数据的缓冲区。我们可以省略这个参数。

  • 第二个参数 (dims) 是一个缓冲区,每个条目都是一个维度;所以对于一个一维数组,它可以是长度为 1 的缓冲区(甚至是一个整数,因为每个整数都是长度为 1 的缓冲区)

  • 由于第二个参数是缓冲区,第一个参数 (nd) 指定了它的长度

  • 第三个参数 (typenum) 表示类型。


例如,假设你在 x 中有 4 个 64 位整数:

要创建一个数组,请使用

int dims[1];
dims[0] = 4;
PyArray_SimpleNewFromData(1, dims, NPY_INT64, x)

要创建一个2X2矩阵,请使用

int dims[2];
dims[0] = dims[1] = 2;
PyArray_SimpleNewFromData(2, dims, NPY_INT64, x)

有这样的代码:float fArray[5] = {0,1,2,3,4}; npy_intp m = 14; PyObject *c ; c = PyArray_SimpleNewFromData(1,&m,NPY_FLOAT,(void *)fArray);请问这段代码中有什么错误,因为我遇到了分段错误。 - Sajal Jain
抱歉 - 看起来没问题。您确定段错误是由此引起的吗?您能在这行代码前后加上printf语句输出一下吗? - Ami Tavory
我对此处 x 的求值方式感到困惑。前三个参数对我来说很清楚。 - Sajal Jain
6
你提供了一个可以容纳5个项目的缓冲区fArray,但是告诉它有14个项目的空间(m),这会在尝试访问时导致分段错误。话虽如此,你的问题更可能是由于没有在模块初始化时调用import_array()引起的,请参考这里 - Jaime
1
@AmiTavory 我会考虑开一个新问题。然而,我找到了问题所在,变量在函数返回时被删除了。当使用新命令创建数组时,它可以正常工作。 - Tony
显示剩余12条评论

1
确保修补上述方法中存在的内存泄漏。我猜测上面的x是一个类型为void *的指针。查看this

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接