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

p.lavarre at ieee.org p.lavarre at ieee.org
Thu Sep 28 19:42:01 EDT 2006


> 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

As concise as I now can imagine, yes thank you.

I see the main point leads: "The truth value of any NULL ctypes pointer
instance is False."  That angle neatly ducks my ongoing newbie
confusion over a null constructed in Python via c_void_p(0) being
different from a null constructed in C via return (void *) 0.

> ...
> > And so then the next related Faq is:
> >
> > Q: How should I test for ((void *) -1)?
>
> For me, on Windows, c_void_p(-1).value is the same
> as c_void_p(0xFFFFFFFF).value, but it is -1 not 0xFFFFFFFF.

Different results at my desk.  Specifically, I see:

>>> from ctypes import * ; c_void_p(-1).value
4294967295L
>>>

in Mac OS X 10.4.7 Python 2.5 r25:51918 and Win XpSp2 Python 2.5
r25:51908.

> 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

Exactly what I should have written, yes, thank you.

And somewhat generalisable: c_void_p(0).value is None.

Maybe this is the thing that's been astonishing me: maybe C often does
return the .value of the pointer, rather than a new instance of the
POINTER class?

> and your test would become
> (ctypes.cast(pv, ctypes.c_void_p).value == INVALID_HANDLE_VALUE

Yes.

Mind you, typing out all that noise inspires me to ask, does (pv ==
INVALID_HANDLE_VALUE) give the wrong answer for any pv other than
c_void_p(-1)?  In other words, if by convention I get all my pointers
from C and never construct a pointer in Python except to take its
value, then can I safely write the more obvious translation of (pv ==
INVALID_HANDLE_VALUE)?

> 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.

I'm interested, if you can make the time to say more ...

> 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.

Good.

> ...
> might be better to use another wiki for ctypes, maybe the python.org one, for this
> stuff.) ...

Could be.  Offline I heard we might have more pages coming soon.
Checking at random just now, I see http://wiki.python.org/moin/ is
"immutable", so I guess I can't add "A Wiki page to collect the Faq's
highlit by Clp" to the "Starting points" > "Asking for Help" >
"Wanted...">




More information about the Python-list mailing list