如何有效地将2d python列表提供给c++;扩展模块 我在C++中编写了一个Python 3.5模块,我想从Python到C++输入一个2D列表,最好是一个STD::vector。工作代码如下,但我希望可以避免复制数据,而是将2d数组指

如何有效地将2d python列表提供给c++;扩展模块 我在C++中编写了一个Python 3.5模块,我想从Python到C++输入一个2D列表,最好是一个STD::vector。工作代码如下,但我希望可以避免复制数据,而是将2d数组指,python,c++,module,Python,C++,Module,如何有效地将2d python列表提供给c++;扩展模块 我在C++中编写了一个Python 3.5模块,我想从Python到C++输入一个2D列表,最好是一个STD::vector。工作代码如下,但我希望可以避免复制数据,而是将2d数组指向地址和输入值。有更好的方法吗 PyObject* CheckTerminal(PyObject* self, PyObject* args) { PyObject *input_value; std::vector<std::v

如何有效地将2d python列表提供给c++;扩展模块

我在C++中编写了一个Python 3.5模块,我想从Python到C++输入一个2D列表,最好是一个STD::vector。工作代码如下,但我希望可以避免复制数据,而是将2d数组指向地址和输入值。有更好的方法吗

PyObject* CheckTerminal(PyObject* self, PyObject* args)
{
  PyObject *input_value;
  std::vector<std::vector<bool>> cArray;

  if (!PyArg_ParseTuple(args, "O", &input_value))
  {
    std::cout << "\nerror\n";
    goto error;
  }

  int count = (int)PyList_Size(input_value);
  PyObject *ptemp,*vals;

  for (int i = 0; i < count; i++)
  {
    cArray.push_back(std::vector<bool>());
    ptemp = PyList_GetItem(input_value, i);
    int count2 = (int)PyList_Size(ptemp);
    for (int j = 0; j < count2; ++j)
    {

        vals = PyList_GetItem(ptemp, j);
        int v = PyLong_AsLong(vals);

        if (v == 1)
        {
            cArray[i].push_back(true);
        }
        else if (v == 0)
        {
            cArray[i].push_back(false);
        }

    }

  }

  return PyBool_FromLong(g.CheckTerminal(&cArray));

error:
  return 0;
}

我通过使用PyObjor而不是转换为C++数组来解决这个问题。pyobject内的数据访问由PyList_GetItem或PyList_GetSlice完成

// Checks if given boardState is terminal. 
PyObject* NInARowGame::CheckTerminal(PyObject* input_value)
{

    //this is just  check, should be the same number of planes.
    PyObject *p1 = PyList_GetItem(input_value, 0);
    PyObject *p2 = PyList_GetItem(input_value, 1);
    Py_INCREF(p1);
    Py_INCREF(p2);

    int count = (int)PyList_Size(input_value);

    auto nK = this->winsK.size();

    for (int i = 0; i<nK; ++i)
    {//for each winning kernel do the following
     //int ksizeY = k[0].size();

        if (compareK(p1, &this->winsK[i]))
        {
            winner = 1;
            return Py_True;

        }
        if (compareK(p2, &this->winsK[i]))
        {
            winner = 2;
            return Py_True;
        }


    }
    PyObject *m = this->GetMoves(); 
    int counter = (int)PyList_Size(m);

    if (counter==0) 
    {
        winner = 3;
        return Py_True;

    }
    Py_DECREF(p1);
    Py_DECREF(p2);
    return Py_False;
}
//检查给定的boardState是否为terminal。
PyObject*NinaRowName::CheckTerminal(PyObject*输入值)
{
//这只是检查,应该是相同数量的飞机。
PyObject*p1=PyList\u GetItem(输入值,0);
PyObject*p2=PyList\u GetItem(输入值,1);
Py_增量(p1);
Py_增量(p2);
int count=(int)PyList_大小(输入值);
auto nK=this->winsK.size();
对于(int i=0;iwinsK[i]))
{
获胜者=1;
返回Py_True;
}
if(比较(p2,&this->winsK[i]))
{
获胜者=2;
返回Py_True;
}
}
PyObject*m=this->GetMoves();
int计数器=(int)PyList_尺寸(m);
如果(计数器==0)
{
获胜者=3;
返回Py_True;
}
Py_DECREF(p1);
Py_DECREF(p2);
返回Py_False;
}

问题在于Python列表是指针数组,而不是值数组,不是吗?为了完整起见,还有一个已定义的脚本可用,非常接近:#define PyList_GET_ITEM(op,i)(((PyListObject*)(op))->ob ITEM[i])
// Checks if given boardState is terminal. 
PyObject* NInARowGame::CheckTerminal(PyObject* input_value)
{

    //this is just  check, should be the same number of planes.
    PyObject *p1 = PyList_GetItem(input_value, 0);
    PyObject *p2 = PyList_GetItem(input_value, 1);
    Py_INCREF(p1);
    Py_INCREF(p2);

    int count = (int)PyList_Size(input_value);

    auto nK = this->winsK.size();

    for (int i = 0; i<nK; ++i)
    {//for each winning kernel do the following
     //int ksizeY = k[0].size();

        if (compareK(p1, &this->winsK[i]))
        {
            winner = 1;
            return Py_True;

        }
        if (compareK(p2, &this->winsK[i]))
        {
            winner = 2;
            return Py_True;
        }


    }
    PyObject *m = this->GetMoves(); 
    int counter = (int)PyList_Size(m);

    if (counter==0) 
    {
        winner = 3;
        return Py_True;

    }
    Py_DECREF(p1);
    Py_DECREF(p2);
    return Py_False;
}