3

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.

2
  • 1
    You're creating a buffer, but not using it. What are you trying to do? Usually, you'd want to use something like PyBuffer_FillInfo, but it's not clear what the goal here is. Buffers must be associated with a Python object, is data_s as PyObject of some sort? Commented Nov 17, 2015 at 2:39
  • @ShadowRanger: You might be right. I was attempting to use the Py_buffer in the PyTuple_SetItem() call. I am trying to call an arbitrary function with arbitrary data. Maybe it isn't valid to set the buffer PyObject to a tuple like that? I did see some documentation on the PyBuffer_FillInfo function, but I was assuming that the PyObject* exporter needed to exist before I could use it to set the value of the Py_buffer. It seemed the opposite direction for what I need. Commented Nov 17, 2015 at 4:08

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.