Python ctypes: Python文件对象 <-> C FILE *
我正在使用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。