sean
sean

Reputation: 71

Python C-API: Populate a Py_buffer from a C function

I am having a really hard time figuring out how to pass a large byte array of data from C to an arbitrary Python3 function. For reference, here are some documentation links on the subject:

https://docs.python.org/3.5/extending/embedding.html

Most of the information in the docs seems to assume that I am passing data from Python to C. I need to do the opposite. I found the a reference to the API function PyBuffer_FromContiguous – but it is not documented anywhere (that I can find). The function prototype is here:

PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf,
                                        Py_ssize_t len, char order);

Basically I have two questions:

  1. Is this the right way to construct a Py_buffer object? Is this even the right approach?
  2. Once the Py_buffer is constructed, how do I associate the Py_buffer with a PyObject that can be set to a input tuple/argument for a call to a python function?

Here is a code sample for what I am attempting (updated to include the data_s typedef):

typedef struct
{
  size_t size;
  unsigned char* data;
} data_s;

  // convert the arguments
  PyObject* pArgs;
  PyObject* pRes;
  Py_buffer* pBuf;
  pArgs = PyTuple_New((Py_ssize_t)num_args);
  if (num_args)
  {
    va_start(argp, num_args);
    for (i = 0; i < num_args; i++)
    {
      data_s* arg = va_arg(argp, data_s*);
      result = PyBuffer_FromContiguous(pBuf, arg->data, (Py_ssize_t)arg->size, 'C');
      if (result < 0)
      {
        fprintf(stderr, "Error: Unable to copy argument %d into python object\n", i);
        PY_DECREF(pArgs);
        break;
      }

      // set pValue, something like this?
      PyTuple_SetItem(pArgs, i, pBuf->obj);
    }
  }

  // run the function
  pRes = PyObject_CallObject(func_entry->pFunc, pArgs);

  // error checking... 

… I would really appreciate any leads on these issues.

Upvotes: 3

Views: 1568

Answers (1)

sean
sean

Reputation: 71

The problem was that I was not finding the right API call for what I needed. Here is the call (in case anyone cares) that solves this problem: Py_BuildValue and is documented here:

https://docs.python.org/3/extending/extending.html#building-arbitrary-values

Upvotes: 1

Related Questions