2016-06-27 14 views
1

ich einen Named Pipes-Server mit einer Hauptschleife, wo ich Daten aus einem Rohr lese:Python ctypes create_string_buffer() Fehler 0xC0000005

while True: 
     bytes_available = DWORD() 
     ret_code = windll.kernel32.PeekNamedPipe(pipe, None, 0, None, byref(bytes_available)) 
     if ret_code == 0 and windll.kernel32.GetLastError() == ERROR_BROKEN_PIPE: 
      reconnect() 
     buf = create_string_buffer(bytes_available.value) 
     ret_code = windll.kernel32.ReadFile(pipe, byref(buf), bytes_available.value, None, overlapped_struct_ptr) 
     if ret_code != 0 and bytes_available.value > 0: 
      # process(buf.raw) 
      pass 
     elif ret_code == 0 and windll.kernel32.GetLastError() == ERROR_BROKEN_PIPE: 
      reconnect() 
     windll.kernel32.GetQueuedCompletionStatus(iocp, byref(bytes_transferred), byref(completion_key), 
                byref(overlapped_struct_ptr), INFINITE) 

Manchmal stürzt es auf den create_string_buffer() Schritt mit der folgenden Meldung:

Prozess beendet mit Exit-Code -1073741819 (0xC0000005)

Dies scheint mir fremd, denn wenn ichersetzenmit (c_char*bytes_available.value)() alles funktioniert gut. Und wenn wir an der create_string_buffer() Implementierung betrachten, werden wir sehen, dass es die auf die gleiche Weise puffern zuordnet:

def create_string_buffer(init, size=None): 
    """create_string_buffer(aString) -> character array 
    create_string_buffer(anInteger) -> character array 
    create_string_buffer(aString, anInteger) -> character array 
    """ 
    if isinstance(init, (str, unicode)): 
     if size is None: 
      size = len(init)+1 
     buftype = c_char * size 
     buf = buftype() 
     buf.value = init 
     return buf 
    elif isinstance(init, (int, long)): 
     buftype = c_char * init 
     buf = buftype() 
     return buf 
    raise TypeError(init) 

Warum also nicht wahr?

+1

'windll.kernel32.PeekNamedPipe()' Aufruf in Ihrem Code scheint ein Argument fehlt, sollte es sechs, [msdn] (https://msdn.microsoft.com/en-us/library/windows/ desktop/aa365779 (v = vs.85) .aspx) –

+0

Bingo! Ich entschied mich, das letzte Argument wegzulassen, weil es das letzte war und als optional gekennzeichnet wurde. Und ich ignorierte den Hinweis "Dieser Parameter kann NULL sein, wenn keine Daten gelesen werden sollen." Das Lustige ist, es hat funktioniert, bis ich viele Druckanweisungen im Code zum Debuggen von Puprosen hatte. Python stürzt ab, nachdem ich Druckanweisungen für den Puffer entfernt habe. Könnten Sie eine Antwort hinzufügen? Ich werde es akzeptieren. – wombatonfire

Antwort

1

windll.kernel32.PeekNamedPipe() Aufruf in Ihrem Code scheint ein Argument fehlt, sollte es sechs sein; siehe msdn

Das Weglassen eines Arguments verursachte im Wesentlichen undefiniertes Verhalten.