c - 将 io._BufferedReader 传递给 c 函数

标签 c cpython python-3.2

这个问题是我的 previous question 的后续问题,我试图为 Python3 编译 python-yenc。在被告知没有快速修复方法后,我决定接受挑战并完全重写它。

我唯一想不通的是如何将 PyArg_ParseTupleAndKeywords 与 io-objects 一起使用。相关代码如下:

PyObject *in_file, *out_file;
static char *kwlist[] = { "infile", "outfile", NULL };

if(!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!|l", kwlist,\
                     &PyBytes_Type, &in_file,\
                     &PyBytes_Type, &out_file,\
                     &bytes)) return NULL;

这显然产生了

Traceback (most recent call last):
  File "test.py", line 21, in <module>
    print(_yenc.decode_file(b), outfile=o)
TypeError: argument 1 must be bytes, not _io.BufferedReader

如何将 _io.BufferedReader 对象传递给我的函数?

谢谢, 马丁

最佳答案

Mzialla,你不应该使用“O!”在 PyArg_ParseTupleAndKeywords 中。这样做意味着您不能传递指定类型以外的任何对象。我相信在 Python 3.2 扩展中与文件交互的典型方法不是假定任何特定类型,而是针对“协议(protocol)”进行编程。

所以你应该这样做:

if(!PyArg_ParseTupleAndKeywords(args, kwds, "OO|l", kwlist,\
             &in_file, &out_file, &bytes))
    ...

之后,您有两个选择:使用其 Python 方法与流对象交互,或者获取流的文件描述符 (PyObject_AsFileDescriptor) 并使用操作系统级 read 对其进行操作/write功能(或同等功能)。

对于 Python 方法,您应该获取“read”方法,并调用它而不是 fread。以下内容(未经测试):

PyObject *read = PyObject_GetAttrString(in_file, "read");
if (!read) handle_error;
while(encoded < bytes || bytes == 0) {
    PyObject *bytes_obj= PyObject_CallFunction(read, "i", 1);
    if (!bytes || !PyBytes_Check(bytes_obj)) handle_error;
    char *s = PyBytes_AS_STRING(bytes_obj);
    ...
}

然后您需要为写入端做类似的事情。

关于c - 将 io._BufferedReader 传递给 c 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450386/

相关文章:

c - C语言如何制作对称矩阵

python - `ExceptionTable` 的输出中的 `dis` 是什么?

python - 对 C 的标注可以预估 Python 字典的容量吗?

python - python中pickle.dump的使用

python 通过管道进行进程通信 : Race condition

python - 令人困惑的名称错误

c++ - 未找到 opencv .dll 文件

c - Mikroc 中的函数声明

c - Microsoft 编译器和 GNU 编译器在输出可执行文件大小方面的差异

python - CPython 中的字符串乘法是如何实现的?