Python | Passing filenames to extension in C



Code # 1: Write an extension function that gets the filename

static PyObject * py_get_filename (PyObject * self, PyObject * args)

{

PyObject * bytes; 

char * filename; 

Py_ssize_t len; 

 

if (! PyArg_ParseTuple (args, " O & amp; " , PyUnicode_FSConverter, & amp; bytes)) {

return NULL; 

}

 

  PyBytes_AsStringAndSize (bytes, & amp; filename, & amp; len); 

/ * Use filename * /

/ * Clean up and return * /

Py_DECREF (bytes)

Py_RETURN_NONE; 

}

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

Code # 2:

/ * Object with file name * /
PyObject * obj; 
PyObject * bytes; 

 

char * filename; 

Py_ssize_t len; 

 
bytes = PyUnicode_EncodeFSDefault (obj); 
PyBytes_AsStringAndSize (bytes, & amp; filename, & amp; len); 

 
/ * Use filename * /
...

/ * Cleanup * /

Py_DECREF (bytes); 

If the filename needs to be passed back to Python use the following the code below —

Code # 3:

/ * Turn file name into Python object * /

char * filename; 

int filename_len; 

PyObject * obj = PyUnicode_DecodeFSDefaultAndSize (

filename, filename_len); 

Working with filenames in a portable way — a tricky problem best left to Python. Filenames will be treated as if anyone had used the above in the C extension code.

Passing open files to C extensions —

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

PyObject * fobj; 

int fd = PyObject_AsFileDescriptor (fobj); 

if (fd & lt; 0) {

return NULL; 

}

The resulting file descriptor is obtained by calling fileno () in fobj . So any object that provides a handle in this way should work (like file, socket, etc.). The descriptor can be passed to various low-level C functions that expect to work on files.  PyFile_FromFd () is used to convert an integer file descriptor back to a Python object.

Code # 5:

/ * Existing file descriptor (already open) * /

int fd; 

 

PyObject * fobj = PyFile_FromFd (fd, "filename" ,

"r" , -1, NULL, NULL, NULL, 1); 

PyFile_FromFd () arguments reflect arguments to the built-in open () function. NULL values ​​simply indicate that default options for encoding, errors, and newline arguments are used.