Python|将文件名传递给 C 中的扩展名
在将文件名传递给 C 库函数之前,必须根据系统预期的文件名编码对文件名进行编码。
代码#1:编写一个接收文件名的扩展函数
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;
}
如果已经存在需要转换为文件名的PyObject *
,则使用下面给出的代码:
代码#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);
如果要将文件名返回给Python,请使用下面给出的以下代码 -
代码#3:
/* Turn a filename into a Python object */
char* filename;
int filename_len;
PyObject* obj = PyUnicode_DecodeFSDefaultAndSize(
filename, filename_len);
以可移植的方式处理文件名是一个棘手的问题,最好留给Python。如果在扩展 C 代码中使用上述文件名,文件名将以一种方式处理。
将打开的文件传递给 C 扩展 -
代码 #4:要将文件转换为整数文件描述符,请使用PyFile_FromFd()
PyObject* fobj;
int fd = PyObject_AsFileDescriptor(fobj);
if (fd < 0) {
return NULL;
}
通过调用fobj上的fileno()
方法获得生成的文件描述符。因此,以这种方式公开描述符的任何对象都应该可以工作(例如,文件、套接字等)。可以将描述符传递给期望处理文件的各种低级 C 函数。 PyFile_FromFd()
用于将整数文件描述符转换回Python对象。
代码#5:
/* Existing file descriptor (already open) */
int fd;
PyObject* fobj = PyFile_FromFd(fd, "filename",
"r", -1, NULL, NULL, NULL, 1);
PyFile_FromFd()
的参数反映了内置 open()函数的参数。 NULL 值仅表示正在使用编码、错误和换行参数的默认设置。