На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Оптимизация асинхронного I/O в COM порт , многопоточность
    Доброго времени суток, уважаемые!
    ExpandedWrap disabled
      Платформа WIN32, ОС ХР, комилятор BCB 6.xx

    Собственно в чем вопрос - проблема в том, что в потоке в цикле висит алгоритм который проверяет WaitCommEvent(), ERROR_IO_PENDING, наличие данных в очереди - ComStat.cbInQue ну и так далее, и все такое. Все замечательно, все работает, но очень уж беспокоит то, что загрузка ЦП очень высока. Пока обрабатывается один порт одним потоком, все вроде бы и ничего, но в реальности будет обрабатываться много (примерно 30~50) портов, я так полагю, ситуация значительно ухудшится. :(
    Этому есть разумное решение программным способом? ;)
      вот пример из моей проги, может будет полезен. Когда данных для чтения нет, то поток чтения просто ждет когда появятся данные, а не проверяет постоянно очередь.
      инициализация ком порта
      ExpandedWrap disabled
            char  strNamePort[ 150 ] = { 0 };
            sprintf( strNamePort, "COM%d:", nComPort );
            m_hComPort = CreateFile( strNamePort,
                GENERIC_READ | GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                NULL );
         
        ...........
                        if ( SetCommMask( m_hComPort, EV_RXCHAR ) )
                        {
         
                            COMMTIMEOUTS   TimeOuts;
         
                            if ( GetCommTimeouts( m_hComPort, &TimeOuts ) )
                            {
                                TimeOuts.ReadIntervalTimeout         = 40;
                                TimeOuts.ReadTotalTimeoutMultiplier  = 0;  
                                TimeOuts.ReadTotalTimeoutConstant    = 0;  
                                TimeOuts.WriteTotalTimeoutMultiplier = 0;
                                TimeOuts.WriteTotalTimeoutConstant   = 0;
         
                                if ( SetCommTimeouts( m_hComPort, &TimeOuts ) )
                                {

      функция чтение крутиться в цикле в отдельном потоке, вот кусок.
      ExpandedWrap disabled
        // pSiem->m_hComPort - хэндл ком порта
        // pSiem->m_hEventEndThread - событие что надо закончить поток чтения.
            DWORD   nBytesRead = 0;
            bool bFlag = true;
            while ( bFlag )
            {
         
                // если тут, значит все ок и данные записали, читаем ответ
                DWORD       dwCommEvent;
                DWORD       dwOvRes = 0;
         
                // ивент события ком порта
                OVERLAPPED  osStatus = { 0 };
                osStatus.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
                if ( osStatus.hEvent == NULL )
                {
                    TRACE( "ERROR: ивет для события ком порта не создался!\n" );
                    return;
                }
         
                if ( !WaitCommEvent( pSiem->m_hComPort, &dwCommEvent, &osStatus ) )
                {
                    if ( GetLastError( ) == ERROR_IO_PENDING )
                    {
                        // все ок, ждем события
                    }
                    else
                    {
                        CloseHandle( osStatus.hEvent );
                        char message[ 200 ] = { 0 };
                        sprintf( message, "ERROR: WaitCommEvent failed, error = %d!\n", GetLastError( ) );
                        TRACE( message );
                        return;
                    }
                }
                else
                {
                    // плохо, не понятная ошибка
                    CloseHandle( osStatus.hEvent );
                    char message[ 200 ] = { 0 };
                    sprintf( message, "ERROR: WaitCommEvent failed, error = %d!\n", GetLastError( ) );
                    TRACE( message );
                    return;
                }
         
                // ожидаем события не чтение или закрываем поток на чтение
                HANDLE hEv[ 2 ];
                hEv[ 0 ] = pSiem->m_hEventEndThread;
                hEv[ 1 ] = osStatus.hEvent;
                DWORD dwRes = WaitForMultipleObjects( 2, hEv, FALSE, INFINITE );
                switch( dwRes )
                {
                    case WAIT_OBJECT_0:
                        bFlag = false;
                        // завершаем поток
                        break;
                    case WAIT_OBJECT_0 + 1:
                        if ( !GetOverlappedResult( pSiem->m_hComPort, &osStatus, &dwOvRes, FALSE ) )
                        {
                            // плохо, не понятная ошибка
                            CloseHandle( osStatus.hEvent );
                            char message[ 200 ] = { 0 };
                            sprintf( message, "ERROR: GetOverlappedResult failed, error = %d!\n", GetLastError( ) );
                            TRACE( message );
                            return;
                        }
                        else
                        {
                            CloseHandle( osStatus.hEvent );
                            // ивент чтения
                            OVERLAPPED  osRead = { 0 };
                            osRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
                            if ( osRead.hEvent == NULL )
                            {
                                TRACE( "ERROR: инет для чтения не создался!\n" );
                                return;
                            }
         
                            COMSTAT     Comstatus;
                            DWORD       dwError;
         
                            ClearCommError( pSiem->m_hComPort, &dwError, &Comstatus );
                            char * buffer = new char [ Comstatus.cbInQue + 1 ];
                            memset( buffer, 0, Comstatus.cbInQue + 1 );
                            if ( !ReadFile( pSiem->m_hComPort, buffer, Comstatus.cbInQue, &nBytesRead, &osRead ) )
                            {
                                DWORD dwLastError = GetLastError( );
                                if( dwLastError != ERROR_IO_PENDING )
                                {
                                    // ошибка чтения
                                    CloseHandle( osRead.hEvent );
                                    char message[ 200 ] = { 0 };
                                    sprintf( message, "ERROR: ReadFile failed, error = %d!\n", dwLastError );
                                    TRACE( message );
                                    return;
                                }
                                else
                                {
                                    DWORD fRes = WaitForSingleObject( osRead.hEvent, INFINITE );
                                    switch ( fRes )
                                    {
                                        case WAIT_OBJECT_0:
                                            if ( !GetOverlappedResult( pSiem->m_hComPort, &osRead, &nBytesRead, FALSE))
                                            {
                                                // ошибка чтения
                                                CloseHandle( osRead.hEvent );
                                                char message[ 200 ] = { 0 };
                                                sprintf( message, "ERROR: GetOverlappedResult failed, error = %d!\n", GetLastError( ) );
                                                TRACE( message );
                                                return;
                                            }
                                            else
                                            {
                                                        // All ok.
                                            }
                                            break;      
                                        default:
                                            {
                                                // ошибка чтения
                                                CloseHandle( osRead.hEvent );
                                                char message[ 200 ] = { 0 };
                                                sprintf( message, "ERROR: Хрен знает что за ошибка, error = %d!\n", GetLastError( ) );
                                                TRACE( message );
                                                return;
                                            }
                                    };
                                }
                            }
                            else
                            {
                                // All ok.
                            }

      в конце по идее в переменной buffer будет прочитанные символы
      что непонятно спрашивайте.
        Спасибо, буду пока разбираться, помоему, то что нужно! :yes:
          Используй ReadFile в отдельных потоках, проверено, работает надежно. Дело в том, что приведенный выше пример немного медленней работает и при высокой скорости работы порта может пропускать байты, вернее буфер порта переполняется и байты теряются.
            sploid, я бы чуток упростил программу, учитывая, что ожидание завершения OVERLAPPED-операции может делать сам GetOverlappedResult с флагом bWait = TRUE.
              флаг bWait выставляется в фальс, когда надо завершить поток чтения, т.е. когда случится событие pSiem->m_hEventEndThread.
                sploid, это у тебя для ожидания WaitCommEvent сделано, а для чтения нет, тем более, что можно завершение потока по-другому реализовать, например вручную сигнализировать ивент или просто прибить тред.
                  Спасибо всем еще раз, возник такoй вопрос:
                  Обрисую ситуацию - порядка 30-50 портов, на каждый порт свой поток, пока я данные в порт не отправил и не получил ответ от устройства - делать потоку собственно нечего т.е. дальнейшее выполнение целиком зависит от результатов предыдущих шагов(как я понимаю основная фишка асинхронного метода в продолжении работы потока не заботясь о завершении записи/считывания информации).
                  В моем случае есть ли какой-либо смысл использовать асинхронный I/O?
                  Или проще(и проще ли?) использовать в каждом потоке синхронный метод?

                  И еще одно :) Порылся поиском по сайту, накопал много доков по портам, в одном из них нашел пример, но вот чего я понять не могу(я все-таки пока далеко не эксперт по портам ;) ) - так это почему он так странно работает? Посылаешь ему команду (любую) - во входном буфере ловишь ее имя и все. Никакого тебе ответа от оборудования. Когда делал асинхронно - все было иначе. Вот пример...
                  Цитата

                  #include <windows.h>
                  #include <iostream.h>
                  #include <conio.h>

                  void main(void)
                  {
                  DCB dcb;
                  COMMTIMEOUTS ct;
                  HANDLE hPort;
                  DWORD bc;
                  DWORD mask;

                  char *buf_out="ATI3";
                  char *buf_in;

                  dcb.DCBlength=sizeof(DCB);
                  BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb);
                  dcb.fNull=TRUE;

                  ct.ReadIntervalTimeout=10;
                  ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;
                  ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;

                  hPort=CreateFile("COM3",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
                  if(hPort==INVALID_HANDLE_VALUE) {
                  MessageBox(NULL,"Невозможно открыть последовательный порт","Error",MB_OK);
                  ExitProcess(1);
                  }

                  SetCommState(hPort,&dcb);
                  SetCommTimeouts(hPort,&ct);
                  PurgeComm(hPort,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
                  SetupComm(hPort,256,256);

                  SetCommMask(hPort,EV_RXCHAR);

                  buf_in=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,strlen(buf_out)+1);
                  cout<<"\nWRITTE\t"<<buf_out;
                  WriteFile(hPort,buf_out,strlen(buf_out),&bc,NULL);
                  WaitCommEvent(hPort,&mask,NULL);
                  ReadFile(hPort,buf_in,strlen(buf_out),&bc,NULL);
                  cout<<"\nREAD\t"<<buf_in;

                  HeapFree(GetProcessHeap(),0,buf_in);
                  CloseHandle(hPort);
                  getch();
                  }
                    Используй вместо своей конструкции
                    WaitCommEvent(hPort,&mask,NULL);
                    ReadFile(hPort,buf_in,strlen(buf_out),&bc,NULL);
                    Вот эту
                    if( ReadFile(hPort, buf_in, strlen(buf_out), &bc, 0)){
                    if (bc > 0){/*что то делаем*/}
                    }
                    ReadFile не вернет управления, пока не заполнит буфер либо не возникнет сбой/таймаут. Совсем необязательно, что буфер будет заполнен, нужно проверять, что bc>0. Асинхронно порт работает только в 98windows, NT/XP вроде только синхронный.
                      Цитата Паровоз @
                      Асинхронно порт работает только в 98windows, NT/XP вроде только синхронный.
                      Чушь

                      Добавлено
                      Цитата Coffee @
                      Посылаешь ему команду (любую) - во входном буфере ловишь ее имя и все. Никакого тебе ответа от оборудования. Когда делал асинхронно - все было иначе.

                      Странная и непонятная фраза: что значит "ловить имя команды"? Какой ответ от какого оборудования?
                        Цитата Adil @
                        Чушь

                        К сожалению, не чушь - сам недавно напоролся на эту фигню. Недавно эту проблему уже обсуждали на форуме.
                        При попытке записать синхронно в порт, тред, который пишет, - блокируется, пока не разблокируется тред, в котором данные из порта синхронно читаются.
                        Т.е. пока используется либо только синхронное чтение, либо только синхронная запись - всё ОК, совместно они друг друга блочат.

                        Пришлось переходить к псевдо-синхронной схеме, т.е. использовать асинхронные вызовы ReadFile/WriteFile, а потом ожидать сигнализации события о завершении операции.

                        Добавлено
                        Coffee, при таком количестве портов, возможно, имеет смысл не плодить кучу тредов, а создать пул тредов, каждый из которых будет обрабатывать несколько портов. В таком случае, после запуска операции асинхронно, тебе надо будет, например, с помощью GetOverlappedResult пробегаться по списку ивентов, связанных с операциями по каждому порту. Теоритически, можно рискнуть это сделать в одном треде (но у меня есть ощущение, что не будет успевать).

                        В UNIXах c этим проще - select умеет работать не только с сокетами, но и с дескрипторами обычных файлов и устройств, а в Windows данная возможность не реализована.
                          Цитата Adil @
                          Цитата Паровоз @
                          Асинхронно порт работает только в 98windows, NT/XP вроде только синхронный.
                          Чушь

                          Добавлено
                          Цитата Coffee @
                          Посылаешь ему команду (любую) - во входном буфере ловишь ее имя и все. Никакого тебе ответа от оборудования. Когда делал асинхронно - все было иначе.

                          Странная и непонятная фраза: что значит "ловить имя команды"? Какой ответ от какого оборудования?

                          2 Паровоз
                          "ReadFile не вернет управления, пока не заполнит буфер либо не возникнет сбой/таймаут." - верно, он буфер пока не заполнит, он не вернет, но он чем-то не тем его заполняет... и BC>0 тут не катит... чтобы понять что я имею ввиду см. мой ответ Adil

                          2 Adil
                          Поясню что это значит.
                          1. Асинхронный вариант
                          Посылаю команду ATZ получаю ответ от оборудования - что-то типа "ATZ\r\n\r\nOK\r\n" во входном буфере.
                          Посылаю команду ATH1 получаю ответ от оборудования - что-то типа "\r\nOK\r\n" во входном буфере и характерный звук модема.

                          1. Синхронный вариант (исходник см.выше)
                          Посылаю команду ATZ получаю во входном буфере "ATZ".
                          Посылаю команду ATH1 получаю во входном буфере "ATH1" и никакого звука от модема.


                          2 exodus
                          В одном потоке помоему точно не стоит ;)
                          Так тот исходник что я кинул будет работать под ХР? или под 2000/ХР синхронная запись/чтение - в моем случае не покатят? Непонимаю... :wall: в мсдн вроде написано мол и то можно и то, только примеры лежат под OVERLAPPED вариант...
                            Coffee, в MSDN написано, что синхронно читать/писать можно, но реалии таковы, то это дело работает только на Win95-98, а на линейке NT5 (2k, XP, 2003) не пашет, про NT4 и ранее не в курсе - не пробовал, так что про синхронную работу - забудь. У меня правда получается работать синхронно с WaitCommEvent, при том, что дескриптор порта открыт с флагом OVERLAPPED, но в доке написано, что такой режим не рекомендуется.

                            Добавлено
                            Собственно вот тема, где обсуждается блокировка при синхронном в/в: [COM-порт]синхронная запись/мониторинг
                              Слушай, а может тебе проверить провода на счет замыкания 2и3 пина. Если они замкнуты, то и ответы будут такими странными. И еще вариант, то, что оборудование такое.
                                Цитата Паровоз @
                                Слушай, а может тебе проверить провода на счет замыкания 2и3 пина. Если они замкнуты, то и ответы будут такими странными. И еще вариант, то, что оборудование такое.

                                2 exodus все понятно, OVERLAPPED forever :)
                                2 Паровоз нет, там стоит PCI модем на котором я и извращаюсь, когда получится с ним перейду на другое оборудование. Да и не может быть так, что одни и те же команды работают асинхронно и не работают синхронно. ИМХО - либо кривая прога - либо виндовый механизм синхронного I/O в ХР...
                                  И снова приветствую всех!
                                  Есть большая просьба - у кого есть модем внутренний или внешний или подобное оборудование - проверьте пожалуйста, будет ли у вас работать этот код. У меня PCI модем на COM3 у товарища - обычный модем на СОМ2. У меня все прекрасно работает - у него - нет. Понять причину немогу.
                                  Если кто подскажет в чем дело - буду очень признателен.
                                  ExpandedWrap disabled
                                    #include <windows.h>
                                    #include <conio.h>
                                    #include <iostream.h>
                                    #define MAX 1024
                                     
                                    DWORD WINAPI ThreadFunc(LPVOID lpParam );
                                    void Error(void);
                                    bool Terminate=TRUE;
                                    HANDLE hPort = NULL;
                                    char *temp;
                                     
                                    void main(void)
                                    {
                                    //Запрашивам имя порта
                                    clrscr();
                                    temp=(char*)calloc(MAX,sizeof(char));
                                    strcpy(temp,"\n\nВведите номер открываемого порта, например COM1 или COM3\n\n");
                                    CharToOem((const char*)temp,(char*)temp);
                                    cout<<temp;
                                    memset(temp, '\0',MAX);
                                    cin>>temp;
                                     
                                    //открываем порт
                                    hPort=CreateFile(temp,
                                                     GENERIC_WRITE|GENERIC_READ,
                                                     0,
                                                     NULL,
                                                     OPEN_EXISTING,
                                                     FILE_FLAG_OVERLAPPED,
                                                     NULL);
                                    if(hPort!=INVALID_HANDLE_VALUE){
                                       cout<<"\nOpenPort - ok\n";}
                                       else{
                                           Error();getch();exit(1);
                                           }
                                    //проводим настройку порта
                                    DCB          *dcb;
                                    COMMTIMEOUTS  ct;
                                     
                                    //скорости, четности, битность битов, стоп биты...
                                    dcb=(DCB*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DCB));
                                    dcb->DCBlength=sizeof(DCB);
                                    BuildCommDCB("baud=9600 parity=N data=8 stop=1",dcb);
                                    dcb->fNull=TRUE;
                                     
                                    //таймауты порта
                                    ct.ReadIntervalTimeout=10;
                                    ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;
                                    ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;
                                     
                                    SetCommState(hPort,dcb);
                                    SetCommTimeouts(hPort,&ct);
                                     
                                    //очистка порта перед работой очищаем все что можно
                                    PurgeComm(hPort,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
                                    SetupComm(hPort,256,256); //последние два параметра - длина вх.\ вых. буфера
                                    SetCommMask(hPort,EV_RXCHAR); //маска ожидания символа во входном буфере
                                     
                                    //Запускаем поток на чтение порта
                                     
                                    DWORD lpThreadId;
                                    HANDLE hThread = CreateThread(
                                        (LPSECURITY_ATTRIBUTES) NULL,   // pointer to thread security attributes
                                        (DWORD) 0,                          // initial thread stack size, in bytes
                                        (LPTHREAD_START_ROUTINE) &ThreadFunc,  // pointer to thread function
                                        (LPVOID) &hPort,                         // argument for new thread
                                        (DWORD) 0,                          // creation flags
                                        (LPDWORD) &lpThreadId               // pointer to returned thread identifier
                                       );
                                     
                                    //Работаем с пользователем
                                    for(;Terminate==TRUE;)
                                    {
                                    strcpy(temp,"\n\nВведите команду, например ATI1-ATI7 или ATZ\nВыход - восклицательный знак '!'\n");
                                    CharToOem((const char*)temp,(char*)temp);
                                    cout<<temp;
                                    memset(temp, '\0',MAX);
                                    cin>>temp;
                                     
                                    if(strcmp(temp,"!")==0)
                                      {
                                      TerminateThread(hThread,1);
                                      clrscr();
                                      cout<<"\nBye!\n";
                                      exit(0);
                                      }
                                     
                                    DWORD dwWrite ;
                                    OVERLAPPED OverWrite;
                                    strcat(temp,"\r\n");
                                     
                                    OverWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                                    if (OverWrite.hEvent == NULL)
                                       {
                                       cout<<"\n\nError creating write event\n\n"; Error(); exit(1);
                                       }
                                    if (!WriteFile(hPort, temp, sizeof(temp),&dwWrite, &OverWrite))
                                        {
                                        if(GetLastError() != ERROR_IO_PENDING)
                                           {
                                           cout<<"\n\nError writing port\n\n"; Error(); exit(1);
                                           }
                                         }
                                    else
                                        {
                                        cout<<"\n\nWrited to port\n"<<temp;
                                        }
                                    //getch();    
                                    }
                                     
                                    getch();
                                    }
                                     
                                     
                                    DWORD WINAPI ThreadFunc(LPVOID lpParam )
                                    {
                                    Terminate=TRUE;
                                    HANDLE hPort=*(HANDLE*)lpParam;
                                    COMSTAT ComStat;
                                    DWORD dwMask, dwError, dwRead;
                                    OVERLAPPED OverRead;
                                    char Buf[100]="";
                                     
                                    OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                                    if (OverRead.hEvent == NULL)
                                       {
                                       cout<<"\n\nError creating read event\n\n"; Error(); exit(1);
                                       }
                                    while (Terminate)
                                        {
                                        if (!WaitCommEvent(hPort, &dwMask,(LPOVERLAPPED)&OverRead))
                                          {
                                          if (GetLastError() == ERROR_IO_PENDING){
                                              WaitForSingleObject(OverRead.hEvent, INFINITE);
                                              }
                                          else{
                                              cout<<"\n\nError waiting port event\n\n"; Error(); exit(1);
                                              }
                                           }
                                        if (!ClearCommError(hPort, &dwError, &ComStat))
                                           {
                                           cout<<"\n\nError clearing port\n\n"; Error(); exit(1);
                                           }
                                     
                                        dwRead = ComStat.cbInQue;
                                        if(dwRead > 0)
                                          {
                                         if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))
                                            {
                                            cout<<"\n\nError reading port\n\n"; Error(); exit(1);
                                            }
                                           // В Buf находятся прочитанные байты
                                           // идет обработка принятых байтов ...
                                           cout<<"\n\n*****************************\n"<<
                                           "DATA_FROM_PORT:\n"<<(char*)Buf<<
                                                 "\n*****************************\n";
                                           memset(Buf, '\0', strlen(Buf) - 1);
                                         }
                                        }
                                    return 0;
                                    }
                                     
                                    void Error(void)
                                    {
                                    LPVOID lpMsgBuf;
                                    FormatMessage(
                                        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
                                        GetLastError(),
                                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                        (LPTSTR) &lpMsgBuf,
                                        0,
                                        NULL);
                                    CharToOem((const char*)lpMsgBuf,(char*)lpMsgBuf);
                                    cout<<"\n\nGetLastError:\n\n"<<(const char*)lpMsgBuf<<"\n\n";
                                    LocalFree( lpMsgBuf );
                                    }
                                    надо выкладывать не код, а солюшен, что бы не трахаться с созданием нового проекта, удалением оттуда файлов, вставкой новых.

                                    т.к. порт открыт как оверлапед, то
                                    Цитата

                                    ExpandedWrap disabled
                                      if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))
                                              {
                                              cout<<"\n\nError reading port\n\n"; Error(); exit(1);
                                              }


                                    если не считалось то нормально и нужно ждать события OverRead.hEvent ( когда считается), а не выходить с ошибкой.

                                    в чем проблема, почему не работает на другом компе?
                                    Сообщение отредактировано: sploid -
                                      ExpandedWrap disabled
                                        if (!WriteFile(hPort, temp, sizeof(temp),&dwWrite, &OverWrite))

                                      Размер указателя? Ты уверен что так правильно? ;)
                                      ExpandedWrap disabled
                                        OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                                        ...
                                        WaitForSingleObject(OverRead.hEvent, INFINITE);

                                      У тебя эвент с мануальным сбросом, но, что-то не где не видно чтоб ты его сбрасывал...
                                      ExpandedWrap disabled
                                        char Buf[100]="";
                                        ...
                                        dwRead = ComStat.cbInQue;
                                        ...
                                        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))

                                      А не ты разве простраивал буффер в 256? Шанс схлопотать исключение не велик, но если схлопочешь - мало не покажется...
                                      ExpandedWrap disabled
                                        BuildCommDCB("baud=9600 parity=N data=8 stop=1",dcb);

                                      А остальные настройки у ваших компов одинаковые?
                                        Цитата sploid @
                                        надо выкладывать не код, а солюшен, что бы не трахаться с созданием нового проекта, удалением оттуда файлов, вставкой новых.

                                        Как я уже писал у меня компилятор - BCB 6.0 какие в нем солюшены - я не знаю. И так весь VCL убрал дабы совместимость была, и консоль - по тойже причине.
                                        Цитата sploid @

                                        т.к. порт открыт как оверлапед, то
                                        Цитата
                                        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))
                                        {
                                        cout<<"\n\nError reading port\n\n"; Error(); exit(1);
                                        }
                                        если не считалось то нормально и нужно ждать события OverRead.hEvent ( когда считается), а не выходить с ошибкой.

                                        Кстати, валится именно на этом... Может я не так как-то делаю... Сделал так:
                                        ExpandedWrap disabled
                                          if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))
                                                  {
                                                  WaitForSingleObject(OverRead.hEvent, INFINITE);
                                                         ....
                                                  }

                                        Теперь вечно висит на WaitForSingleObject ... мда короче. Разбираться еще и разбираться...
                                        Цитата sploid @

                                        в чем проблема, почему не работает на другом компе?

                                        Работаем удаленно - другой комп в другом городе. Сказать 100% точно - не могу. Но 99,9% проблема в том что вышеописанная конструкция - корявая, как впрочем видимо и все остальное. :(


                                        Цитата Ace @
                                        if (!WriteFile(hPort, temp, sizeof(temp),&dwWrite, &OverWrite))

                                        Размер указателя? Ты уверен что так правильно?

                                        Косяк, спасибо, учтем.

                                        Цитата Ace @

                                        OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                                        ...
                                        WaitForSingleObject(OverRead.hEvent, INFINITE);

                                        У тебя эвент с мануальным сбросом, но, что-то не где не видно чтоб ты его сбрасывал...

                                        Да честно говоря - х.з. смотрел в МСДНе исходники их. Вроде тоже нигде не сбрасывают. А может и сбрасывают, там такое наворочено, что черт ногу сломит. :wall: Буду еще смотреть.

                                        Цитата Ace @

                                        char Buf[100]="";
                                        ...
                                        dwRead = ComStat.cbInQue;
                                        ...
                                        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead))

                                        А не ты разве простраивал буффер в 256? Шанс схлопотать исключение не велик, но если схлопочешь - мало не покажется...

                                        Самое малое из моих зол... ;) :D :lool:
                                        Цитата Ace @

                                        BuildCommDCB("baud=9600 parity=N data=8 stop=1",dcb);
                                        А остальные настройки у ваших компов одинаковые?


                                        Да вроде бы да. При таких же параметрах HyperTerminal пашет ...

                                        В общем тему пока закрывать не буду. Попробую еще с исходниками с МСДНа разобраться. Если поставить эти параметры туда, их прога - катит. На этом можно было бы и остановиться, но меня бесят две вещи - уровень собственного понимания этой проблемы (над этим надо работать...) и весь тот зоопарк с ресурсами, критическими секциями, десятью отдельными *.с файлами в проекте и прочей мишурой из МСДН сурсов... >:( Короче работы по горло.
                                        Всем большое спасибо что откликнулись - буду искать дальше. :)
                                        1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                        0 пользователей:


                                        Рейтинг@Mail.ru
                                        [ Script execution time: 0,0677 ]   [ 15 queries used ]   [ Generated: 20.11.25, 07:06 GMT ]