P_get for the 'P' pointer type uses PyLong_FromVoidPtr . If the address matches the long platform, it returns Python int ; otherwise, it returns a Python long that has variable precision. This is fine, but when passing this integer value as an argument, the default behavior is to convert to C int , which is 32-bit on all supported platforms.
I think the best solution is to set argtypes to properly convert the argument to a pointer type. Another option is to set restype to a subclass of c_void_p . Using a subclass disables conversion to a Python integer. GetResult checks this by calling _ctypes_simple_instance , which actually returns the opposite of what its name and original comment suggests. (In 2.5, this function was called IsSimpleSubType , and the original comment was erroneous even then. The βsimpleβ in the question was never a metaclass PyCSimpleType , but the base type is _SimpleCData .)
POSIX:
>>> _ctypes_simple_instance(c_void_p) 0 >>> _ctypes_simple_instance(my_void_p) 1 >>> malloc.restype = c_void_p >>> type(malloc(100)) <type 'int'> >>> malloc.restype = my_void_p >>> type(malloc(100)) <class '__main__.my_void_p'>
Window:
_ctypes_simple_instance not exported _ctypes.pyd.
from ctypes import * malloc = cdll.msvcrt.malloc class my_void_p(c_void_p): pass
>>> malloc.restype = c_void_p >>> type(malloc(100)) <class 'int'> >>> malloc.restype = my_void_p >>> type(malloc(100)) <class '__main__.my_void_p'>
source share