Python ctypes: Python文件对象 <-> C FILE *

11 投票
6 回答
9305 浏览
提问于 2025-04-16 04:35

我正在使用ctypes这个工具,把一个我能控制的C库用Python包裹起来。我想要包裹一个C函数,函数的声明如下:

int fread_int( FILE * stream );

现在,我想在Python中打开一个文件,然后以某种方式使用Python的文件对象,获取到底层的FILE *对象,并把它传递给这个C函数:

# Python
fileH = open( file , "r")
value = ctypes_function_fread_int( ????? )
fileH.close()

请问,Python的文件对象和C语言的FILE *对象之间的映射有可能实现吗?

Joakim

6 个回答

3

如果你想使用 stdout(标准输出)、stdin(标准输入)和 stderr(标准错误),你可以从标准C库中导入这些变量。

libc = ctypes.cdll.LoadLibrary('libc.so.6')
cstdout = ctypes.c_void_p.in_dll(libc, 'stdout')

或者,如果你出于某种原因想避免使用 void*

class FILE(ctypes.Structure):
    pass

FILE_p = ctypes.POINTER(FILE)

libc = ctypes.cdll.LoadLibrary('libc.so.6')
cstdout = FILE_p.in_dll(libc, 'stdout')
29

一个Python文件对象不一定有一个底层的C级别的FILE *,至少在你不想把代码绑定到特定的Python版本和平台时,是这样的。

我建议你使用Python文件对象的fileno来获取一个文件描述符,然后用ctypes调用C运行时库的fdopen,这样就可以从这个描述符创建一个FILE *。这种方法非常通用(你也可以反过来做)。主要的问题是,使用同一个文件描述符打开的两个对象(Python文件对象和C的FILE *)的缓冲区是分开的,所以要确保根据需要经常刷新这些对象(或者,如果这样更方便并且与你的使用方式兼容,可以把它们都设置为无缓冲)。

-1

我也遇到过同样的问题。

看看这个文件:

http://svn.python.org/projects/ctypes/trunk/ctypeslib/ctypeslib/contrib/pythonhdr.py

你可以从中使用 PyFile_AsFile。

撰写回答