Передача массива / кортежа из python обратно в c ++ - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь передать список в python из cpp и забираю его обратно. Первоначально я пытался передать одно значение и вернуть одно значение. Это сработало. Теперь я пытаюсь передать полный массив / список. Ниже приведен мой cpp код:

#include <iostream>
#include <Python.h>
#include <numpy/arrayobject.h>
#include <typeinfo>
using namespace std;

int main()
{
Py_Initialize();
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString("."));

PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;

// Build the name object
pName = PyString_FromString("mytest");

// Load the module object
pModule = PyImport_Import(pName);

// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);

// pFunc is also a borrowed reference 
pFunc = PyObject_GetAttrString(pModule, "stuff");

if (!PyCallable_Check(pFunc))
  PyErr_Print();

PyObject *list = PyList_New (5);

Py_ssize_t size = PyList_GET_SIZE(list);

for(Py_ssize_t s = 0; s < size; s++ )
{
    PyList_SetItem(list, s, Py_BuildValue("d", 2.5));

}

PyObject* result = PyObject_CallObject(pFunc, list);
if(result==NULL)
{cout << "FAILED ..!!" << endl;}

cout << result << endl;;
return 0;
}   

Я всегда получаю сообщение "FAILED .. !!".

Вот мой mytest.py

def stuff(a):
   x=a
   return x

Есть предложения, где я могу ошибаться?

1 Ответ

2 голосов
/ 02 марта 2020

Из документации :

PyObject * PyObject_CallObject (PyObject * callable, PyObject * args)
Это эквивалент выражения Python: callable ( * args).

Принимая во внимание, что PyObject_CallFunctionObjArgs задокументировано как:

PyObject * PyObject_CallFunctionObjArgs (PyObject * callable, ..., NULL)
Это эквивалент выражения Python: callable (arg1, arg2, ...).

Поэтому измените свой вызов на следующее:

PyObject* result = PyObject_CallFunctionObjArgs(pFunc, list, NULL);

(или вы можете заключить в оболочку ваш список внутри другого списка и продолжайте использовать CallObject, но это гораздо более простое решение)

...