[pypy-issue] [issue1655] ctypes errcheck protocol different from cpython implementation

Roman Valov tracker at bugs.pypy.org
Sun Dec 8 09:11:38 CET 2013


New submission from Roman Valov <roman.valov at gmail.com>:

Hi, folks.

Currently I'm working on bindings for C-based library using ctypes and once 
bindings were complete I've tried to test them using PyPy. The library I'm 
working on have a lots of function definitions that return pointer to the list 
with number of items in the list returned via passed-by-ref argument.

Here is example of C source:

#include <stdio.h>

int data[] = { -1, -2, -3, -4 };

int *get_data(char const *tag, int *len)
{
	printf("tag: %s\n", tag);

	*len = sizeof(data) / sizeof(data[0]);
	return data;
}

Once saved as sample.c, it should be compiled to shared library:

gcc sample.c -o libsample.so -fPIC -shared


Next, I'd wrapped such functions using both paramflags and errcheck 
functionality of ctypes function prototypes. Here is it:

#!/usr/bin/python

from ctypes import cdll, CFUNCTYPE, POINTER, c_int, c_char_p

lib = cdll.LoadLibrary('./libsample.so')

def ret_list_p(icount):
    def sz_array_p(obj, func, args):
        print (repr(obj))
        print (repr(args))
        return [ obj[i] for i in range(args[icount].value) ]
    return sz_array_p

get_data_prototype = CFUNCTYPE(POINTER(c_int), c_char_p, POINTER(c_int))
get_data_paramflag = ((1,), (2,))
get_data_signature = ('get_data', lib)

get_data = get_data_prototype( get_data_signature, get_data_paramflag )

print get_data('noerrcheck')

get_data.errcheck = ret_list_p(1)

print get_data('doerrcheck')



Once this code is invoked with CPython implementation I've got following result:

tag: noerrcheck
4
tag: doerrcheck
<__main__.LP_c_int object at 0x7ffb124775f0>
('doerrcheck', c_int(4))
[-1, -2, -3, -4]

but with PyPy I'm faced with errors due to errcheck got python wrapper args, but 
not args binded function was called with:

tag: noerrcheck
4
tag: doerrcheck
<_ctypes.pointer.LP_c_int object at 0x00007f27b7d62250>
('doerrcheck',)
Traceback (most recent call last):
  File "app_main.py", line 72, in run_toplevel
  File "./sample.py", line 24, in <module>
    print get_data('doerrcheck')
  File "/usr/lib/pypy/lib_pypy/_ctypes/function.py", line 343, in __call__
    result = self._do_errcheck(result, args)
  File "/usr/lib/pypy/lib_pypy/_ctypes/function.py", line 387, in _do_errcheck
    v = self._errcheck_(result, self, args)
  File "./sample.py", line 11, in sz_array_p
    return [ obj[i] for i in range(args[icount].value) ]
IndexError: tuple index out of range

----------
files: sample.py
messages: 6407
nosy: pypy-issue, reddot
priority: bug
status: unread
title: ctypes errcheck protocol different from cpython implementation

________________________________________
PyPy bug tracker <tracker at bugs.pypy.org>
<https://bugs.pypy.org/issue1655>
________________________________________


More information about the pypy-issue mailing list