[Tutor] ctypes question

eryksun eryksun at gmail.com
Wed Oct 10 13:40:31 CEST 2012


On Wed, Oct 10, 2012 at 6:02 AM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> elif pf.startswith("lin"):
>     libc = ctypes.CDLL("libc.so.6")
>     fopen = libc.fdopen

> fh = fopen(ctypes.c_char_p(fn), "rb")
> fhPtr = ctypes.byref(ctypes.c_int(fh))
> buff = ctypes.create_string_buffer(lines)
> ret = libc.fread(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fhPtr)
> print buff.value

fdopen takes a file descriptor, not a filename. You're using it with a
filename like fopen (and you even called it fopen). Also, the byref
usage is incorrect. fopen() returns a pointer to a FILE. fread() needs
the pointer, not a reference to the pointer. You're giving it the
address of an int, but it expects to find a FILE. You can use
c_void_p(fh), or set the argtypes.

    >>> from ctypes import *
    >>> import ctypes.util

    >>> libc = cdll.LoadLibrary(ctypes.util.find_library('c'))
    >>> fopen = libc.fopen
    >>> fread = libc.fread
    >>> fread.argtypes = [c_void_p, c_size_t, c_size_t, c_void_p]

    >>> fh = fopen("spam.txt", "rb")
    >>> buf = create_string_buffer(128)
    >>> fread(buf, 1, 128, fh)
    5
    >>> buf.value
    'spam\n'

To use fdopen, you can get a fileno() from an open Python file object:

    >>> f = open("spam.txt", "rb")

    >>> fdopen = libc.fdopen
    >>> fh = fdopen(f.fileno(), "rb")
    >>> fread(buf, 1, 128, fh)
    5


More information about the Tutor mailing list