On Thu, May 5, 2016 at 10:42 AM, Joseph L. Casale <jcas...@activenetwerx.com> wrote: > I have CDLL function I use to get a pointer, several other functions happily > accept this > pointer which is really a long when passed to ctypes.c_void_p. However, only > one with > same type def in the prototype overflows. Docs suggest c_void_p takes an int > but that > is not what the first call returns, nor what all but one function happily > accept?
What you're describing isn't clear to me, so I'll describe the general case of handling pointers with ctypes functions. If a function returns a pointer, you must set the function's restype to a pointer type since the default c_int restype truncates the upper half of a 64-bit pointer. Generally you also have to do the same for pointer parameters in argtypes. Otherwise integer arguments are converted to C int values. Note that when restype is set to c_void_p, the result gets converted to a Python integer (or None for a NULL result). If you pass this result back as a ctypes function argument, the function must have the parameter set to c_void_p in argtypes. If argtypes isn't set, the default integer conversion may truncate the pointer value. This problem won't occur on a 32-bit platform, so there's a lot of carelessly written ctypes code that makes this mistake. Simple types are also automatically converted when accessed as a field of a struct or union or as an index of an array or pointer. To avoid this, you can use a subclass of the type, since ctypes won't automatically convert subclasses of simple types. I generally avoid c_void_p because its lenient from_param method (called to convert arguments) doesn't provide much type safety. If a bug causes an incorrect argument to be passed, I prefer getting an immediate ctypes.ArgumentError rather than a segfault or data corruption. For example, when a C API returns a void pointer as a handle for an opaque structure or object, I prefer to handle it as a pointer to an empty Structure subclass, as follows: class _ContosoHandle(ctypes.Structure): pass ContosoHandle = ctypes.POINTER(_ContosoHandle) lib.CreateContoso.restype = ContosoHandle lib.DestroyContoso.argtypes = (ContosoHandle,) ctypes will raise an ArgumentError if DestroyContoso is called with arguments such as 123456789 or "Crash Me". -- https://mail.python.org/mailman/listinfo/python-list