Как настроить тайм-аут чтения USB-порта в C++ (VS2010)?

Я открываю и читаю порт с USB-устройства (термопринтер):

HANDLE hUsb = CreateFile(symbolicName,
      GENERIC_READ | GENERIC_WRITE, 
      0, 
      NULL, 
      OPEN_EXISTING, 
      0, 
      NULL);

ReadFile(hUsb, buffer, bytes, &read, NULL);

Мне нужно настроить тайм-аут для чтения, но это USB-порт, а не COM-порт, поэтому я не могу использовать функцию SetCommTimeouts.

Есть ли какая-либо функция, которую я могу использовать и которая имеет тот же эффект, что и SetCommTimeouts?

Если есть простой способ, я предпочитаю не использовать поток.

Я использую Visual Studio 2010 с Windows 10.

Благодарный.


person Bruno    schedule 22.10.2018    source источник
comment
Я не очень разбираюсь в окнах, но дикая догадка - может ли помочь порт завершения ввода-вывода?   -  person SergeyA    schedule 22.10.2018
comment
вам нужно создать асинхронный дескриптор. в результате ReadFile не блокируется. и вы можете отменить вызов в любое время   -  person RbMm    schedule 22.10.2018


Ответы (1)


в первую очередь никакая Visual Studio тут абсолютно не причем.

общее решение - используйте асинхронный ввод-вывод, который никогда не блокируется. и вы можете самостоятельно отменить операцию io по некоторому тайм-ауту. хороший способ, конечно, установить таймер (через CreateTimerQueueTimer) и отменить ввод-вывод в обратном вызове таймера. или если io завершится до этого - отменить таймер. но если нужна простейшая реализация, которая выполняет синхронный ввод-вывод на месте - можно сделать следующее:

    inline ULONG BOOL_TO_ERROR(BOOL f)
    {
        return f ? NOERROR : GetLastError();
    }

    //------------------------------------------------------------------------

    HANDLE hFile = CreateFileW(symbolicName, FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED, 0);

    if (hFile != INVALID_HANDLE_VALUE)
    {
        OVERLAPPED ov = {};
        if (ov.hEvent = CreateEventW(0, 0, 0, 0))
        {
            char buf[16];
            ULONG NumberOfBytesRead = 0;
            ULONG err = BOOL_TO_ERROR(ReadFile(hFile, buf, sizeof(buf), 0, &ov));

            switch (err)
            {
            case ERROR_IO_PENDING:
                if (WaitForSingleObject(ov.hEvent, timeout) != WAIT_OBJECT_0)
                {
                    CancelIo(hFile);
                }
            case NOERROR:
                err = BOOL_TO_ERROR(GetOverlappedResult(hFile, &ov, &NumberOfBytesRead, TRUE));
                break;
            }

            CloseHandle(ov.hEvent);
        }
        CloseHandle(hFile);
    }
person RbMm    schedule 22.10.2018