Python | Передача имен файлов в расширение на C

Опубликовано: 12 Апреля, 2022

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
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;
}

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

Code#2 :

/* 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);

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

Code #3 :

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

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()

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

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 :

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

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.

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.