Python3 segfaults when using ctypes on xlib, python2 works
Question: The following code was scrounged up on the Internet years ago and works quite
well in python2. It supplies the current idle time on the X server.

    
    
    import ctypes, os, subprocess
    class XScreenSaverInfo( ctypes.Structure ):
        _fields_ = [("window",     ctypes.c_ulong), ("state",      ctypes.c_int), ("kind",       ctypes.c_int), ("since",      ctypes.c_ulong), ("idle",       ctypes.c_ulong), ("event_mask", ctypes.c_ulong)]
    
    xlib = ctypes.cdll.LoadLibrary("libX11.so.6")
    xss = ctypes.cdll.LoadLibrary("libXss.so.1")
    display = xlib.XOpenDisplay(os.environ["DISPLAY"])
    xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo)
    xssinfo = xss.XScreenSaverAllocInfo()
    
     xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssinfo)
    
     xssinfo.contents.idle
    

I can throw this into a python2.7.10 shell and get what I want. However, doing
the same on a python3.4.3 shell kicks me out with a segmentation fault in this
line

    
    
    xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssinfo)
    

Is my py3 environment broken? Does py3 do something differently?


Answer: There was no significant change in Python 3's `ctypes` module. _However_ in
Python3 `os.environ` values are _unicode_ strings, contrary to the byte
strings of python2 and this [causes the segmentation
fault](http://stackoverflow.com/questions/7256283/differences-in-ctypes-
between-python-2-and-3). So changing:

    
    
    display = xlib.XOpenDisplay(os.environ["DISPLAY"])
    

To:

    
    
    display = xlib.XOpenDisplay(bytes(os.environ["DISPLAY"], 'ascii'))
    

Fixes the segmentation fault.

If you want to have code that works both in python 2 and 3 you want to use the
`encode` method:

    
    
    display = xlib.XOpenDisplay(os.environ["DISPLAY"].encode('ascii'))
    

