Возможно ли получить 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.
Ничего не выйдет, т.к. QSP не только открывает порт в overlapped режиме, но и запускает WaitCommEvents (как минимум), и стартует мониторинг событий на хендле. И как только в порт что-то придет, то QSP автоматически сам вызовет ReadFile. И по аналогии, если вызвать на полученном хендле WriteFile, то QSP автоматом промониторит ее завершение и сделает обработку, т.к. он мониторит открытый хендл на операции ввода-вывода.
QSP::handle() нужен чтобы дать возможность делать некоторые ioctrl's, если ооочень нужно (например, что-нибудь подправить в DCB структуре).
PS: А то что Вы делаете, это порнография (да еще и какая), оно не заработает, или будет постоянно крешиться.
@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
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня есть 4 виджета : startWidget, mainWidget, student widget, teacherWidgetВ startWidget я выбираю который открыть student widget или teacherWidget и на заднем фоне у меня открыт mainWidget