2016-06-27 3 views
1

У меня есть именованный сервер трубы с основным циклом, где я читал данные из трубы:Python ctypes create_string_buffer() Ошибка 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) 

Иногда он падает на create_string_buffer() шаге со следующим сообщением:

Процесс закончил с выходным кодом -1073741819 (0xC0000005)

Это кажется мне странным, потому что, если я заменю create_string_buffer(bytes_available.value) с (c_char*bytes_available.value)() все работает нормально. И если мы посмотрим на create_string_buffer() реализации, мы увидим, что он выделяет буфер таким же образом:

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) 

Так почему же это провал?

+1

'windll.kernel32.PeekNamedPipe()' вызов в вашем коде, кажется, отсутствует аргумент, должно быть шесть, [msdn] (https://msdn.microsoft.com/en-us/library/windows/ desktop/aa365779 (v = vs.85) .aspx) –

+0

Бинго! Я решил опустить последний аргумент, потому что он был последним и помечен как необязательный. И я проигнорировал уведомление «Этот параметр может быть NULL, если данные не должны быть прочитаны». Самое забавное, что это сработало, пока у меня не было много заявлений печати в коде для отладки щенков. Python начал сбой после удаления операторов печати для буфера. Не могли бы вы добавить ответ? Я соглашусь. – wombatonfire

ответ

1

windll.kernel32.PeekNamedPipe() вызов вашего кода, кажется, отсутствует аргумент, должно быть шесть; см. msdn

Опущение аргумента по существу вызвало неопределенное поведение.

Смежные вопросы