Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.06.29;
Скачать: [xml.tar.bz2];

Вниз

Вопрос по overlapped - файлам   Найти похожие ветки 

 
homm ©   (2008-05-14 17:56) [0]

Есть такой код:

{
COMSTAT comstat;  //структура текущего состояния порта, в данной программе используется
   //для определения количества принятых в порт байтов
DWORD btr, temp, mask, signal; //переменная temp используется в качестве заглушки

//создать сигнальный объект-событие для асинхронных операций
overlapped.hEvent = CreateEvent(NULL, true, true, NULL);

//установить маску на срабатывание по событию приёма байта в порт
SetCommMask(COMport, EV_RXCHAR);            
while(условие) //пока поток не будет прерван, выполняем цикл
 {
  //ожидать события приёма байта (это и есть перекрываемая операция)
  WaitCommEvent(COMport, &mask, &overlapped);

  signal = WaitForSingleObject(overlapped.hEvent, INFINITE); //приостановить поток до прихода байта
  if(signal == WAIT_OBJECT_0)            //если событие прихода байта произошло
   {
    if(GetOverlappedResult(COMport, &overlapped, &temp, true)) //проверяем, успешно ли завершилась
       //перекрываемая операция WaitCommEvent
     if((mask & EV_RXCHAR)!=0)    //если произошло именно событие прихода байта
      {
       ClearCommError(COMport, &temp, &comstat);  //нужно заполнить структуру COMSTAT
       btr = comstat.cbInQue;                           //и получить из неё количество принятых байтов
       if(btr)                            //если действительно есть байты для чтения
       {
        ReadFile(COMport, bufrd, btr, &temp, &overlapped);     //прочитать байты из порта в буфер программы
       }
      }
   }
 }
CloseHandle(overlapped.hEvent);  //перед выходом из потока закрыть объект-событие
}


Разве после ReadFile не нужен либо WaitForSingleObject либо уничтожать overlapped.hEvent? Мне кажется что иначе функция возвратится до получения результата. Или я ошибаюсь?


 
Palladin ©   (2008-05-14 18:04) [1]


> Мне кажется что иначе функция возвратится до получения результата.

AFAIK, да, в случае провала ReadFile нужно проверить GetLastError на ERROR_IO_PENDING и дождаться WaitForSingleObject события чтения...


 
DiamondShark ©   (2008-05-14 18:15) [2]


> Разве после ReadFile не нужен либо WaitForSingleObject либо
> уничтожать overlapped.hEvent? Мне кажется что иначе функция
> возвратится до получения результата. Или я ошибаюсь?

После ReadFile нужно проверять результат функции и код ошибки.
Если функция возвратила 0 и GetLastError возвратила ERROR_IO_PENDING, то надо либо ждать WaitForSingleObject, либо звать GetOverlappedResult.

В принципе, этот код, скорее всего ;) будет работать, т.к. до вызова ReadFile в буфере драйвера порта есть какие-то байты, и функция ReadFile, скорее всего ;) завершится синхронно и успешно.

А вообще, в этом фрагменте кода overlapped нафиг не нужен. Аффтор кода запутался в трёх соснах, настроил overlapped в/в, а потом усиленно эмулирует синхронный в/в.

Выкинуть всё нафиг, настроить таймауты и юзать ReadFile в синхронном режиме.


 
homm ©   (2008-05-14 18:18) [3]

А возможно как-то выставить таймауты именно на WaitCommEvent? Что на ReadFile можно — знаю, но вроде не нужно.


 
DiamondShark ©   (2008-05-14 18:21) [4]


> homm ©   (14.05.08 18:18) [3]
> А возможно как-то выставить таймауты именно на WaitCommEvent?

Выкинуть всё -- значит выкинуть всё, включая WaitCommEvent.

Тут никакие евенты, кроме EV_RXCHAR не обрабатываются, значит хватит одной единственной ReadFile в синхронном режиме.
В случае таймаута ReadFile будет возвращать нулевое количество прочитанных байт.


 
homm ©   (2008-05-14 18:23) [5]

> [4] DiamondShark ©   (14.05.08 18:21)
> Тут никакие евенты, кроме EV_RXCHAR не обрабатываются,

Это тут не обрабатывается, а меня больше EV_RXFLAG интересует :)


 
homm ©   (2008-05-14 18:27) [6]

Хотя… Может таймаут на интервал между символами соседними поставить? Скажем 100мс. Минус будет в том, что чаще чем 10 раз в секунду ответ от порта получить не удастся… А так вроде получил нужный символ и сразу вернулся…


 
DiamondShark ©   (2008-05-14 18:32) [7]

Ты пойми, тут код бессмысленный даже без учёта особенностей ReadFile, WaitCommEvent и GetMeSomePizzaPleaseExW.

signal = WaitForSingleObject(overlapped.hEvent, INFINITE); сводит на нет все пляски с бубном вокруг overlapped в/в. Нафига тут overlapped, если поток всё равно безусловно блокируется?


 
DiamondShark ©   (2008-05-14 18:36) [8]


> А так вроде получил нужный символ и сразу вернулся…

А где гарантия, что в буфере до флагового символа не лежит мусор?
Всё равно придётся вычитывать буфер до нужного символа.


 
homm ©   (2008-05-14 18:37) [9]

Это в примере, у меня же нет :) В общем мой вариант:
function TCOMPort.GetResponce: String;
var
 Resive: array [0..255] of Char;
 Errs, NbChars: DWORD;
 Stat: TComStat;
 TransMask, signal: DWORD;
begin
 TransMask := 0;

 fOverlapped.hEvent := CreateEvent(nil, true, true, nil);
 WaitCommEvent(fHandle, TransMask, @fOverlapped);
 signal := WaitForSingleObject(fOverlapped.hEvent, TIMEOUT);
 CloseHandle(fOverlapped.hEvent);

 if (signal <> WAIT_OBJECT_0) then begin
     raise EReadPortTimeout.Create("Write Timeout");
 end;

 result := "";
 // здесь мне не понятно, возможно ли что проверка будет неудачной, если в качестве событий указано только одно — приход флага?
 if (TransMask and EV_RXFLAG) > 0 then begin
    ClearCommError(fHandle, Errs, @Stat);
    NbChars := Stat.cbInQue;
    ReadFile(fHandle, Resive, NbChars, NbChars, @fOverlapped);
    result :=  String(Resive);
 end;
end;


 
DiamondShark ©   (2008-05-14 18:50) [10]

После

> CloseHandle(fOverlapped.hEvent);

вызов

> ReadFile(fHandle, Resive, NbChars, NbChars, @fOverlapped);

страшно даже представить, к чему приведёт.

Закрывай хэндл эвента вместе с файловым хэндлом. Он тебе что, глаза мозолит?

Кстати, hEvent можно ставить в 0. Тогда в качестве хэндла для ожидания можно использовать файловый хэндл.


>  // здесь мне не понятно, возможно ли что проверка будет
> неудачной, если в качестве событий указано только одно —
> приход флага?
>  if (TransMask and EV_RXFLAG) > 0 then begin

Не вызван GetOverlappedResult. В принципе, содержимое TransMask не определено.

проверки результата ReadFile (и GetOverlappedResult, если ERROR_IO_PENDING) опять нет.


> result :=  String(Resive);

Ужос.

SetString(Result, Resive, NbChars);


 
homm ©   (2008-05-14 19:00) [11]

> [10] DiamondShark ©   (14.05.08 18:50)
> После
> > CloseHandle(fOverlapped.hEvent);
> вызов
> > ReadFile(fHandle, Resive, NbChars, NbChars, @fOverlapped);
> страшно даже представить, к чему приведёт.

Дак вроже должен привести к тому, что ReadFile вызовется синхронно и GetOverlappedResult и ERROR_IO_PENDING не понадобятся. Только сильно не ругайте, если ошибаюсь :)


> SetString(Result, Resive, NbChars);

Спасибо :)


 
DiamondShark ©   (2008-05-14 19:12) [12]


> Дак вроже должен привести к тому, что ReadFile вызовется
> синхронно

Это с мусорным-то хэндлом?
Нет. Там должен быть либо валидный хэнл, либо 0.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2008.06.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.044 c
2-1212061268
Max
2008-05-29 15:41
2008.06.29
Открыть файл API


2-1212391354
9899100
2008-06-02 11:22
2008.06.29
Подскажите


15-1210759991
freezon
2008-05-14 14:13
2008.06.29
dxComponentPrinter и cxgrid


2-1212410997
zensan
2008-06-02 16:49
2008.06.29
Множественное наследование


2-1212434898
Jeqa
2008-06-02 23:28
2008.06.29
учет





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский