ctypes.c_void_p(-1) might not be C return (void *) -1
Thomas Heller
theller at python.net
Thu Sep 28 14:41:10 EDT 2006
p.lavarre at ieee.org schrieb:
>> Subject: Python CTypes translation of (pv != NULL)
I've started a wiki page where I already added an entry about the above question.
Do you think the entry would have answered your question?
http://starship.python.net/crew/theller/moin.cgi/CodeSnippets
(My wiki should really be upgraded to a newer moinmoin version, however
it might be better to use another wiki for ctypes, maybe the python.org one, for this
stuff.)
> And so then the next related Faq is:
>
> Q: How should I test for ((void *) -1)?
>
> A:
>
> (pv == 0xffffFFFF) works often.
>
> (ctypes.cast(pv, ctypes.c_void_p).value == 0xffffFFFF) works better.
>
> ((void *) -1) appears often in 32-bit Windows, behind the name
> INVALID_HANDLE_VALUE of the type HANDLE that is def'ed as the type
> PVOID that is def'ed as (void *). -1 is xffffFFFF in 32-bit two's
> complement.
>
> The more complex comparison works more often because specifying a
> restype doesn't decide the __class__ of the result.
True, in principle. For me, on Windows, c_void_p(-1).value is the same
as c_void_p(0xFFFFFFFF).value, but it is -1 not 0xFFFFFFFF.
Worse, on 64-bit systems c_void_p(-1).value is 184467440737009661615, which
is the same as 0xFFFFFFFFFFFFFFFF.
So, to be portable, INVALID_HANDLE_VALUE should be defined like this:
INVALID_HANDLE_VALUE = c_void_p(-1).value
and your test would become
(ctypes.cast(pv, ctypes.c_void_p).value == INVALID_HANDLE_VALUE
Thomas
PS: It is inconsistent that the .value of a c_void_p instance is signed on
32-bit systems, and unsigned on 64-bit systems, but it seems we have to live
with that. Fortunately, the c_void_p constructor accepts both signed and unsigned
Python ints and longs, so it should be possible to work around that fact.
More information about the Python-list
mailing list