Justin Lewis
Justin Lewis

Reputation: 1503

Passing binary data from Python to C API extension

I'm writing a Python (2.6) extension, and I have a situation where I need to pass an opaque binary blob (with embedded null bytes) to my extension.

Here is a snippet of my code:

from authbind import authenticate

creds = 'foo\x00bar\x00'
authenticate(creds)

which throws the following:

TypeError: argument 1 must be string without null bytes, not str

Here is some of authbind.cc:

static PyObject* authenticate(PyObject *self, PyObject *args) {

    const char* creds;

    if (!PyArg_ParseTuple(args, "s", &creds))
        return NULL;
}

So far, I have tried passing the blob as a raw string, like creds = '%r' % creds, but that not only gives me embedded quotes around the string but also turns the \x00 bytes into their literal string representations, which I do not want to mess around with in C.

How can I accomplish what I need? I know about the y, y# and y* PyArg_ParseTuple() format characters in 3.2, but I am limited to 2.6.

Upvotes: 4

Views: 3404

Answers (1)

Justin Lewis
Justin Lewis

Reputation: 1503

Ok, I figured out a with the help of this link.

I used a PyByteArrayObject (docs here) like this:

from authbind import authenticate

creds = 'foo\x00bar\x00'
authenticate(bytearray(creds))

And then in the extension code:

static PyObject* authenticate(PyObject *self, PyObject *args) {

    PyByteArrayObject *creds;

    if (!PyArg_ParseTuple(args, "O", &creds))
        return NULL;

    char* credsCopy;
    credsCopy = PyByteArray_AsString((PyObject*) creds);
}

credsCopy now holds the string of bytes, exactly as they are needed.

Upvotes: 4

Related Questions