Why does Python 2.7 sign extend HDC returned from GetDC() on x64?
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?](http://stackoverflow.com/questions/17840144/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.


Answer: 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_.

