ctypes restype appears to have no effect

Issue #2475 resolved
Graham Markall
created an issue

Compiling the following C source with gcc -shared -fPIC -o libtest.so test.c

int f() { return 0; }
int t() { return 1; }
int t2() { return 2; }

and then executing:

import ctypes
import os

lib = ctypes.CDLL(os.path.join(os.getcwd(), 'libtest.so'))

lib.f.restype = ctypes.c_bool
lib.t.restype = ctypes.c_bool
lib.t2.restype = ctypes.c_bool

print lib.f(), type(lib.f())
print lib.t(), type(lib.t())
print lib.t2(), type(lib.t2())

produces different results between CPython and PyPy. On PyPy 5.6.0 I get:

$ pypy test.py 
0 <type 'int'>
1 <type 'int'>
2 <type 'int'>

whereas with CPython 2.7.13 I get:

$ python test.py 
False <type 'bool'>
True <type 'bool'>
True <type 'bool'>

It appears as if setting restype has no effect - should this be expected to work under PyPy?

Comments (6)

  1. Graham Markall reporter

    It seems that in CFuncPtr._wrap_result (in lib_pypy/_ctypes/function.py, line 605) there is a performance hack which might the cause of this issue:

    # hack for performance: if restype is a "simple" primitive type, don't
    # allocate the buffer because it's going to be thrown away immediately
    if self._is_primitive(restype) and not restype._is_pointer_like():
        return result

    The result is returned directly here instead of a bool being created and returned.

  2. Armin Rigo

    Thanks! Merged the pull request. Note however that ctypes.c_bool stands for the C type bool, from #include <stdbool.h>. If your C functions actually return an int but you declare them as returning ctypes.c_bool, it is only by chance that it will work (it depends on the platform).

  3. Log in to comment