tags:

views:

129

answers:

2

I'm writing a little Python extension in C/C++, and I've got a function like this:

void set_parameters(int first_param, std::list<double> param_list)
{
   //do stuff
}

I'd like to be able to call it from Python like this:

set_parameters(f_param, [1.0, 0.5, 2.1])

Is there a reasonably easy way to make that conversion? Ideally, I'd like a way that doesn't need a whole lot of extra dependencies, but some things just aren't possible without extra stuff, so that's not as big a deal.

A: 

Take a look at Boost.Python. Question you've asked is covered in Iterators chapter of the tutorial

The point is, Boost.Python provides stl_input_iterator template that converts Python's iterable to stl's input_iterator, which can be used to fill your std::list.

Mike Hordecki
A: 

It turned out to be less pain than I thought, once I found the docs that I probably should have read before I asked the question. I was able to get a PyList object in my wrapper function, then just iterate over it and push the values onto the vector I needed. The code looks like this:

static PyObject* py_set_perlin_parameters(PyObject* self, PyObject* args)
{
    int octaves;
    double persistence;
    PyObject* zoom_list;
    int zoom_count = 0;
    std::vector<double> zoom_vector;

    if(!PyArg_ParseTuple(args, "idO!:set_perlin_parameters", &octaves, &persistence, &PyList_Type, &zoom_list))
    {
     return NULL;
    }

    if(!PyList_Check(zoom_list)) 
    {
     PyErr_SetString(PyExc_TypeError, "set_perlin_parameters: third parameter must be a list");
        return NULL;
    }

    zoom_count = PyList_Size(zoom_list);

    for(int i = 0; i < zoom_count; i++)
    {
     PyObject* list_val;
     double val;

     list_val = PyList_GetItem(zoom_list, i);

     if(list_val == NULL)
     {
      return NULL;
     }

     val = PyFloat_AsDouble(list_val);

     zoom_vector.push_back(val);
    }

    set_perlin_parameters(octaves, persistence, zoom_vector);

    return Py_None;
}
Lee Crabtree