[Tutor] ctypes question
Albert-Jan Roskam
fomcl at yahoo.com
Wed Oct 10 14:28:43 CEST 2012
----- Original Message -----
> From: eryksun <eryksun at gmail.com>
> To: Albert-Jan Roskam <fomcl at yahoo.com>
> Cc: Python Mailing List <tutor at python.org>
> Sent: Wednesday, October 10, 2012 1:40 PM
> Subject: Re: [Tutor] ctypes question
>
> 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.
Aha, thanks. Yes, my total lack of knowledge of C speaks volumes here.
> >>> from ctypes import *
> >>> import ctypes.util
>
> >>> libc = cdll.LoadLibrary(ctypes.util.find_library('c'))
That's a nice little trick!
> >>> 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
Very insightful. I'll modify my code an see if it might solve my original problem. At least I've learnt a lot now!
Thanks all for replying!!
More information about the Tutor
mailing list