Python | Passing Filenames to Extension in C

Filename has to be encoded according to the system’s expected filename encoding before passing filenames to C library functions.

Code #1 : To write an extension function that receives a filename

filter_none

edit
close

play_arrow

link
brightness_4
code

static PyObject* py_get_filename(PyObject* self, PyObject* args)
{
    PyObject* bytes;
    char* filename;
    Py_ssize_t len;
  
    if (!PyArg_ParseTuple(args, "O&", PyUnicode_FSConverter, &bytes)) {
        return NULL;
    }
  
    PyBytes_AsStringAndSize(bytes, &filename, &len);
    /* Use filename */
    /* Cleanup and return */
    Py_DECREF(bytes)
        Py_RETURN_NONE;
}

chevron_right


If there is already a existing PyObject * that needs to be converted as a filename, then use the code given below :

Code#2 :

filter_none

edit
close

play_arrow

link
brightness_4
code

/* Object with the filename */
PyObject* obj;
PyObject* bytes;
  
char* filename;
Py_ssize_t len;
  
bytes = PyUnicode_EncodeFSDefault(obj);
PyBytes_AsStringAndSize(bytes, &filename, &len);
  
/* Use filename */
...
    /* Cleanup */
    Py_DECREF(bytes);

chevron_right


If a filename is to be returned back to Python, use the following code given below –

Code #3 :

filter_none

edit
close

play_arrow

link
brightness_4
code

/* Turn a filename into a Python object */
char* filename;
int filename_len;
PyObject* obj = PyUnicode_DecodeFSDefaultAndSize(
    filename, filename_len);

chevron_right


Dealing with filenames in a portable way is a tricky problem that is best left to Python. Filenames will be handled in a manner that, if one uses the above in extension C code.

Passing Open Files to C Extensions –

Code #4 : To convert a file to an integer file descriptor, use PyFile_FromFd()

filter_none

edit
close

play_arrow

link
brightness_4
code

PyObject* fobj;
int fd = PyObject_AsFileDescriptor(fobj);
if (fd < 0) {
    return NULL;
}

chevron_right


The resulting file descriptor is obtained by calling the fileno() method on fobj. Thus, any object that exposes a descriptor in this manner should work (e.g., file, socket, etc.). A descriptor can be passed to various low-level C functions that expect to work with files. PyFile_FromFd() is used to convert an integer file descriptor back into a Python object.

Code #5 :

filter_none

edit
close

play_arrow

link
brightness_4
code

/* Existing file descriptor (already open) */
int fd;
  
PyObject* fobj = PyFile_FromFd(fd, "filename",
                   "r", -1, NULL, NULL, NULL, 1);

chevron_right


The arguments to PyFile_FromFd() mirror those of the built-in open() function. NULL values simply indicate that the default settings for the encoding, errors, and newline arguments are being used.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.