【问题标题】:PyObject_CallObject is returning NULL when trying to pass an arrayPyObject_CallObject 在尝试传递数组时返回 NULL
【发布时间】:2021-07-23 11:18:15
【问题描述】:

我正在尝试将二维数组从 C++ 传递给 Python 函数,但 PyObject_CallObject 函数返回 NULL。这也发生在一维数组的情况下。当我不传递任何参数或参数只是单个变量而不是数组时,它工作正常。我的代码如下:

#include <stdio.h>
#include <Python.h>
#include <pyhelper.hpp>
#include <string>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h> // For capturing the output values given by detector Python inference code

using namespace std;

PyObject *PythonInitialize(string script_name, string function_name);

int main(int argc, char *argv[])
{

    if (!Py_IsInitialized())
    {
        Py_InitializeEx(0); // Initialize the Python interpreter
    }

    PyObject *PythonDetectorFunction, *PythonDetectorFunctionArguments;
    PythonDetectorFunction = PythonInitialize("test", "getsum"); //getint, getsum

    PythonDetectorFunctionArguments = PyTuple_New(1); // Reference count incremented. Need to handle the reference counting
    if (PythonDetectorFunctionArguments == NULL)
        PyErr_Print();

    if (PyArray_API == NULL)
    {
        import_array();
    }

    float data[2][4] = {{1.2, 3.4, 5.6, 7.8}, {1.2, 3.4, 5.6, 7.8}};
    npy_intp dims[2] = {2, 4};

    PythonDetectorFunctionArguments = PyArray_SimpleNewFromData(1, dims, NPY_FLOAT, data);

    PyObject *PythonDetectorFeatureMaps = PyObject_CallObject(PythonDetectorFunction, PythonDetectorFunctionArguments); // Will contain the output given by Python code

    if (PythonDetectorFeatureMaps != NULL)
        printf("PythonDetectorFeatureMaps: %p\n", PythonDetectorFeatureMaps);
    else
        printf("PythonDetectorFeatureMaps is NULL.\n");

    Py_DECREF(PythonDetectorFunction);
    Py_DECREF(PythonDetectorFunctionArguments);
    //Py_DECREF(PythonDetectorFeatureMaps);
}

PyObject *PythonInitialize(string script_name, string function_name)
{
    PyObject *pName, *pModule, *pFunc;
    string PythonCodeImportStatement = "sys.path.append(os.getcwd())";
    PyRun_SimpleString("import sys, os");
    PyRun_SimpleString(PythonCodeImportStatement.c_str()); // Relative path for the python code

    // pNmae is the name of the python script/module to be called
    pName = PyUnicode_FromString(script_name.c_str()); // Reference count incremented. Need to handle the reference counting
    if (pName == NULL)
        PyErr_Print();

    // Getting the Python module reference inside of the C code
    pModule = PyImport_Import(pName);
    if (pModule == NULL)
        PyErr_Print();

    // Python function reference
    pFunc = PyObject_GetAttrString(pModule, function_name.c_str()); // Reference count incremented. Need to handle the reference counting
    if (pFunc == NULL)
        PyErr_Print();

    // Refrence count clean-up
    Py_XDECREF(pName);
    Py_XDECREF(pModule);
    //Py_XDECREF(pFunc);
    return pFunc;
}

test.py 中的 Python 函数:

def getsum(tuple1):
    print('Python function getsum() called')
    return None

谁能指出错误?

【问题讨论】:

  • 你的dims 不应该是{2,4} 吗?
  • 感谢您指出这一点,我已纠正,但问题仍然存在。

标签: python c++ embedding python-embedding


【解决方案1】:

PyObject_CallObject 接受一个可调用对象和一个参数元组作为可调用对象,或者 NULL 表示没有参数。您正在尝试将 NumPy 数组而不是参数元组传递给它。

【讨论】:

  • 是的,根据您的建议,我查看了this 文章,它展示了如何设置元组,因此我相应地更新了我的代码。我创建了元组对象,并使用PyTuple_New(8) 将其大小分配为 8 而不是 1。分配的值如:PyTuple_SetItem( PythonDetectorFunctionArguments, 1, PyFloat_FromDouble( data[0][1] ) ); 但这也导致了同样的方式。
  • @surajj4837:现在您尝试将 8 个参数传递给一个只需要 1 个参数的函数。
  • 我刚刚粘贴了 PyTuple_SetItem 的 1 个示例行。其中第二个参数是要填充的位置。由于字数限制,我无法在此处粘贴所有行。我将部分粘贴。
  • @surajj4837:这就是我认为你正在做的事情(尽管我希望你会使用循环)。这就是将 8 个参数传递给一个需要 1 个参数的函数。
  • PythonDetectorFunctionArguments = PyTuple_New(8); PyTuple_SetItem( PythonDetectorFunctionArguments, 0, PyFloat_FromDouble( data[0][0] )); PyTuple_SetItem( PythonDetectorFunctionArguments, 1, PyFloat_FromDouble( data[0][1] )); PyTuple_SetItem( PythonDetectorFunctionArguments, 2, PyFloat_FromDouble( data[0][2] )); PyTuple_SetItem( PythonDetectorFunctionArguments, 3, PyFloat_FromDouble( data[0][3] ));
猜你喜欢
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多