Re: ctypes.c_void_p(-1) might not be C return (void *) -1



p.lavarre@xxxxxxxx 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.

.



Relevant Pages