首页 > 解决方案 > Ctypes linux行为在py2和py3上有所不同

问题描述

在为 getmntent linux libc 函数编写 python 包装器时,对于以下代码,python 2.x 和 3.x 之间的行为存在一个奇怪的差异,其中大部分实际工作由 C 库完成。由于我经常将 C 代码与 python 接口,任何人都可以解释或更正出了什么问题吗?

import ctypes
import sys

class mntent(ctypes.Structure):
    _fields_ = [("fsname", ctypes.c_char_p),
                ("dir", ctypes.c_char_p),
                ("type", ctypes.c_char_p),
                ("opts", ctypes.c_char_p),
                ("freq", ctypes.c_int),
                ("passno", ctypes.c_int)]

def main():
    libc = ctypes.cdll.LoadLibrary('libc.so.6')
    libc.getmntent.restype = ctypes.POINTER(mntent)
    libc.fopen.restype = ctypes.POINTER(ctypes.c_void_p)
    fp = libc.fopen('/etc/mtab', 'r')
    while True:
        mounts = libc.getmntent(fp)
        if bool(mounts) == False:
            libc.fclose(fp)
            break
        print("%30s   %10s    %s"%(mounts.contents.dir, mounts.contents.type, mounts.contents.fsname))

main()

预期的输出包含列出的所有挂载设备及其类型和挂载点。在 python 3.x 上,它给出了一个空列表。

标签: pythonlinuxctypes

解决方案


在 Python 3 中,所有字符串都是 unicode,但需要libc.fopen()简单的字节字符串作为其参数:

fp = libc.fopen(b'/etc/mtab', b'r')

推荐阅读