1

Тема: Незрозуміла поведінка bool

Доброго всім здоров"я
Пишу на builder 10.4 community, треба реалізувати доступ до ком порта. Скопіпастив функції змережі, трохи відредагував
срр

CSerial::CSerial()
{

    memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
     memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
    m_hIDComDev = NULL;
    m_bOpened = false;

}

CSerial::~CSerial()
{

    Close();

}

bool CSerial::Open(     wchar_t *szPort, int nBaud,int nDataBids,float nStopBits )
{

    if( m_bOpened ) return( TRUE );


    char szComParams[50];
    DCB dcb;


    m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
    if( m_hIDComDev == NULL ) return( FALSE );

    memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
     memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts.ReadTotalTimeoutConstant = 0;
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts.WriteTotalTimeoutConstant = 5000;
    SetCommTimeouts( m_hIDComDev, &CommTimeOuts );



    m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

    dcb.DCBlength = sizeof( DCB );
    GetCommState( m_hIDComDev, &dcb );
    dcb.BaudRate = nBaud;
    dcb.ByteSize = nDataBids;
    dcb.StopBits = nStopBits;
    unsigned char ucSet;
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
    if( !SetCommState( m_hIDComDev, &dcb ) ||
        !SetupComm( m_hIDComDev, 10000, 10000 ) ||
        m_OverlappedRead.hEvent == NULL ||
        m_OverlappedWrite.hEvent == NULL ){
        DWORD dwError = GetLastError();
        if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
        if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
        CloseHandle( m_hIDComDev );
        return( FALSE );
        }

    m_bOpened = TRUE;

    return( m_bOpened );

}

.h

 #include <windows.h>

#ifndef __SERIAL_H__
#define __SERIAL_H__

#define FC_DTRDSR       0x01
#define FC_RTSCTS       0x02
#define FC_XONXOFF      0x04
#define ASCII_BEL       0x07
#define ASCII_BS        0x08
#define ASCII_LF        0x0A
#define ASCII_CR        0x0D
#define ASCII_XON       0x11
#define ASCII_XOFF      0x13

class CSerial
{

public:
    CSerial();
    ~CSerial();

    bool Open( wchar_t  *szPort, int nBaud = 9600,int nDataBids=8,float nStopBits=2 );
    bool Close( void );

    int ReadData( void *, int );
    int SendData( const char *, int );
    int ReadDataWaiting( void );

    bool IsOpened( void ){ return( m_bOpened ); }
    void GetComList(TStringList list);
    
    struct ComPort
{
    ComPort(LPSTR name, LPSTR key);
    ~ComPort();
    LPSTR name;
    LPSTR key;
};

protected:
    bool WriteCommByte( unsigned char );

    HANDLE m_hIDComDev;
    OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
    bool m_bOpened;

};

#endif

та робота з ком портом , це подія. ComPort- обєкт CSerial , StopBitsCBox -комбобокс, LStatus- лейбл

void __fastcall TForm1::Button1Click(TObject *Sender)
{   ShowMessage(BoolToStr(ComPort.IsOpened));
 if(!ComPort.IsOpened)
{
   if(ComPort.Open(ComCBox->Selected->Text.c_str(),BaudCBox->Selected->Text.ToInt(),BitsCBox->Selected->Text.ToInt(),StopBitsCBox->Selected->Text.ToDouble()) )
   {  ShowMessage(BoolToStr(ComPort.IsOpened));
     LStatus->Text="CONNECTED";
     LStatus->TextSettings->FontColor=TAlphaColor(claBlue);
   } else{ShowMessage("Error Com don`t open");}
} else
{
  ComPort.Close();
     LStatus->Text="DISCONNECTED";
     LStatus->TextSettings->FontColor=TAlphaColor(claChocolate);
}

}

Справа в тому, що в конструкторі класу IsOpened одразу ж ініціалізується FALSE але код не виконується, якщо прибрати ! , то все навпаки код виконується, але все одно у функції ComPort.Open не міняється значення чому?

2

Re: Незрозуміла поведінка bool

CSerial::IsOpened - це метод. Його треба викликати. Мені дуже складно сказати, що саме робить тут C++Builder, але схоже, що він розглядає ComPort.IsOpened як адресу метода і перевіряє, чи він не NULL/nullptr.
Додайте після IsOpened дужки ().

Подякували: ijonhson, leofun012

3

Re: Незрозуміла поведінка bool

Але все одно , чомусь вилітає в момент звернення до функції, зробив простіше , переніс m_bOpened до public і звертаюсь до нього напряму, так начебто працює

4

Re: Незрозуміла поведінка bool

Якщо дозволите, ще одне питання, щодо читання з ком порта.
Функція

int CSerial::ReadData( void *buffer, int limit )
{

    if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

    bool bReadStatus;
    DWORD dwBytesRead, dwErrorFlags;
    COMSTAT ComStat;

    ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    if( !ComStat.cbInQue ) return( 0 );

    dwBytesRead = (DWORD) ComStat.cbInQue;
    if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

    bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
    if( !bReadStatus ){
        if( GetLastError() == ERROR_IO_PENDING ){
            WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
            return( (int) dwBytesRead );
            }
        return( 0 );
        }

    return( (int) dwBytesRead );

}

визов функції

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (ComPort.m_bOpened)
{
 char *buff=new char;
 ComPort.ReadData(buff,500) ;
 Memo1->Lines->Add(buff);
}
}

таймер кожні 2 секунди зчитує, післе двох зчитувань eaccess violation

5

Re: Незрозуміла поведінка bool

Дивно, що аж після двох. Ви за адресою, де виділили (нащось) 1 байт, пишете 500.
Крім того, при перетворенні з char* на String стрічка буде обрізана по нульовому символу ('\0'), якщо такий зустрінеться.

Подякували: ijonhson1

6

Re: Незрозуміла поведінка bool

koala написав:

Дивно, що аж після двох. Ви за адресою, де виділили (нащось) 1 байт, пишете 500.
Крім того, при перетворенні з char* на String стрічка буде обрізана по нульовому символу ('\0'), якщо такий зустрінеться.

Так то ж як випало, скільки місця до кінця сторінки віртуальної пам'яті залишилося.

Подякували: ijonhson1

7

Re: Незрозуміла поведінка bool

Дуже дякую, так

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (ComPort.m_bOpened)
{
 char buff[50];
 if(ComPort.ReadData(buff,50))
 {PurgeComm (ComPort.m_hIDComDev,PURGE_RXABORT); }
 Memo1->Lines->Add(buff);

}
}

набагато краще, щодо

koala написав:

при перетворенні з char* на String стрічка буде обрізана по нульовому символу ('\0'), якщо такий зустрінеться.

, то мені не обов"язково прийняти все що іде з ком , тим більше що ардуінку я прописав теж на 2 сек і може не потрапити лише один запис
єдине, що трапляється мусорhttps://replace.org.ua/uploads/images/6602/ba46df2d15d35b4d77941f723ab643f1.png