pythoncpython-3.xpython-c-apipython-extensions

Passing byte string from Python to C


I am writing a python extension in C and I am trying to pass a bytes object to my function. Obviously the 's' token is for strings; I have tried 'O', 'N', and a few others with no luck. Is there a token I can use to parse a bytes object? If not is there an alternative method to parse bytes objects?

static PyObject *test(PyObject *self, PyObject *args)
{
    char *dev;
    uint8_t *key;

    if(!PyArg_ParseTuple(args, "ss", &dev, &key))
        return NULL;

    printf("%s\n", dev);

    for (int i = 0; i < 32; i++)
    {
          printf("Val %d: %d\n", i, key[i]);
    }

    Py_RETURN_NONE;
}

Calling from python: test(b"device", f.read(32)).


Solution

  • If you read the parsing format string docs, it's pretty clear.

    s is solely for getting a NUL terminated UTF-8 encoded C-style string from a str object (so it's appropriate for your first argument, but not your second).

    y* is specifically called out in the docs with (emphasized in original text):

    This is the recommended way to accept binary data.

    y# would also work, at the expense of requiring the caller to provide immutable bytes-like objects, excluding stuff like bytearray and mmap.mmaps.