Возможно ли получить HANDLE с помощью QSerialPort аналогичный HANDLE получаемому с помощью CreateFile (winapi, <windows.h>)?

190
20 мая 2018, 23:00

Возможно ли получить HANDLE с помощью QSerialPort аналогичный HANDLE получаемому с помощью CreateFile (winapi, )?

Есть код написанный на С++ и WinApi, в нем для обращения к устройству порт открывается с помощью:

LPTSTR port_name = TEXT("COM5");
HANDLE hCom = CreateFile((LPCWSTR)port_name,
                    GENERIC_READ | GENERIC_WRITE,
                    0,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL);

Код выше меняю на:

HANDLE hCom;
QSerialPort *serial;
serial = new QSerialPort();
serial->setPortName("COM5");
serial->setBaudRate(QSerialPort::Baud38400);
serial->open(QIODevice::ReadWrite);
hCom = serial->handle();

После этого изменения в коде обмен данными с устройством перестает работать. Код компилируется без ошибок, GetLastError при открытие порта возвращает 0. При записи в порт с помощью WirteFile, GetLastError начинает возвращать ошибку 997 ERROR_IO_PENDING.

Answer 1

Ничего не выйдет, т.к. QSP не только открывает порт в overlapped режиме, но и запускает WaitCommEvents (как минимум), и стартует мониторинг событий на хендле. И как только в порт что-то придет, то QSP автоматически сам вызовет ReadFile. И по аналогии, если вызвать на полученном хендле WriteFile, то QSP автоматом промониторит ее завершение и сделает обработку, т.к. он мониторит открытый хендл на операции ввода-вывода.

QSP::handle() нужен чтобы дать возможность делать некоторые ioctrl's, если ооочень нужно (например, что-нибудь подправить в DCB структуре).

PS: А то что Вы делаете, это порнография (да еще и какая), оно не заработает, или будет постоянно крешиться.

Answer 2

@Geek16bits ERROR_IO_PENDING не является ошибкой.
Данный код обозначает, что операция чтения/записи выполняется асинхронно. Это обусловлено тем, что винапишный код у вас открывает порт в синхронном режиме, а кьют - в асинхронном (флаг FILE_FLAG_OVERLAPPED).

К сожалению, в коде кьют флаг FILE_FLAG_OVERLAPPED проставлен константно и избежать его не удастся. Код:

bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
    ...
    handle = ::CreateFile(reinterpret_cast<const wchar_t*>(systemLocation.utf16()),
                              desiredAccess, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
    ...

Одним из вариантов решения для вас является доп.проверка возвращаемого значения функций ReadFile/WriteFIle на код ошибки ERROR_IO_PENDING
Например так:

    if (ReadFile(m_hPort, buff_current, bytes_to_read, &read_current, &m_ovRead) == FALSE)
    {
        DWORD error_code = 0;
        error_code = GetLastError();
        if (error_code != ERROR_IO_PENDING)
        {
            // Show error
            return 0;
        }
        // Skip empty read attempts
        continue;
    }
   // Append read data to read buffer

Подробнее про FILE_FLAG_OVERLAPPED: http://pblog.ru/?p=74
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx

READ ALSO
Передача файла в ф-ию c++

Передача файла в ф-ию c++

Программа останавливается на строке count = countFile(file); Почему?

235
Помогиите работа с типами данных по C++

Помогиите работа с типами данных по C++

Всем привет, помогите плз с задачкой по с++:( Суть: 1

234
Открывается два виджета одновременно

Открывается два виджета одновременно

У меня есть 4 виджета : startWidget, mainWidget, student widget, teacherWidgetВ startWidget я выбираю который открыть student widget или teacherWidget и на заднем фоне у меня открыт mainWidget

209
Нужен ли тут конструктор копирования

Нужен ли тут конструктор копирования

Вообщем есть такое задание

222