Question

On Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] why is the return value of GetDC() sign extended?

from ctypes import *
hDC1 = windll.user32.GetDC(None)
print hex(hDC1), hDC1, type(hDC1)
hDC2 = windll.user32.GetDC(None)
print hex(hDC2), hDC2, type(hDC2)

Which will sometimes result in negative return values:

 0x6a0116c1  1778456257 <type 'int'>   # OK
-0x53fed994 -1409210772 <type 'int'>   # Why negative?

I believe HANDLES returned by GetDC() always fit within 32bits (even on x64), but cython seems to be sign extending the latter GetDC() return value if the highest bit in the 32 bit value is set (about 50% of the time). Later, attempting to use this negative value HANDLE fails in subsequent GDI calls.

This seems like such a major issue, that I can't understand what I'm missing.

Edit:

This post seems to get to the root of the issue: Why does setting ctypes dll.function.restype=c_void_p return long?

In our case, adding:

class c_void_p(c_void_p): 
pass

to the beginning of the module where restype is defined for each GDI library function seems to have fixed the problem.

Was it helpful?

Solution

ctypes assumes that a function returns a signed int unless you tell it otherwise. Set the function restype to an unsigned value:

from ctypes import *
windll.user32.GetDC.restype = c_void_p
hDC1 = windll.user32.GetDC(None)

ctypes doesn't know anything about parameters and return values, just the entry point of the function. It takes a guess but lets you override with argtypes and restype.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top