2016-06-20 8 views
1

Der folgende Code wurde vor Jahren im Internet gefunden und funktioniert in python2 ziemlich gut. Es liefert die aktuelle Leerlaufzeit auf dem X-Server.Python3 segfaults bei Verwendung von ctypes auf xlib, python2 funktioniert

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 

Ich kann dies in eine Shell python2.7.10 werfen und bekommen, was ich will. Allerdings auf einem python3.4.3 Schale das gleiche zu tun schlägt mich in dieser Linie mit einem Segmentierungsfehler aus

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

Ist meine py3 Umgebung gebrochen? Tut py3 etwas anderes?

Antwort

4

Es gab keine wesentliche Änderung in ctypes Modul von Python 3. Allerdings in Python3 os.environ Werte sind Unicode Strings, im Gegensatz zu den Byte-Strings von Python2 und dies causes the segmentation fault. So verändert sich:

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

An:

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

Fixes die Segmentierungsfehler.

Wenn Sie Code haben wollen, die sowohl in Python funktioniert 2 und 3 Sie die encode Methode verwenden möchten:

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

Danke, das war in der Tat der Fall! – 1N4001

+0

@Bakuriu Noch segfaults für mich bei xlib.XDefaultRootWindow (display) – cass

+0

Ich vermute, es hat mit gtk zu tun, da es auf KDE für mich arbeitet – cass

Verwandte Themen