0

I'm working on a Serial COM Port ANSI Char reading project. I can handle to send data but I can not handle to recieve it. Any help is appriciated.

This is read function:

BOOL ReadString(char *outstring)
{
    int *length;
    *length = sizeof(int);
    BYTE data;
    BYTE dataout[8192]={0};
    int index = 0;
    while(ReadByte(data)== TRUE)
    {
        dataout[index++] = data;
    }
    memcpy(outstring, dataout, index);
    *length = index;
    return TRUE;
}

And Main.cpp is:

int main(void)
{
    //  Configs
    hPort = ConfigureSerialPort("COM1");
    if(hPort == NULL)
    {
        printf("Com port configuration failed\n");
        return -1;
    }


    char* cPTR;
    for(;;)
           {
                ReadString(cPTR);
                if(cPTR!=NULL) cout << "Scanned Data: " << cPTR << endl;
                else cout << "No data recieved." << endl;
    }
    ClosePort();
    return 0;
}
4
  • What goes wrong? cPTR is never initialized, so that may be causing problems, but since you haven't clearly stated what goes wrong, it's hard to say. Commented Aug 13, 2014 at 7:37
  • Did you try to rewrite it with std::string to escape manual memory allocations? Another point is that you have dangerous read without bound checking. Commented Aug 13, 2014 at 8:14
  • int *length; *length = sizeof(int); This is quite enough for crash. Commented Aug 13, 2014 at 8:22
  • 1
    If input data contains 0 in the middle, remaining data will be lost. COM port is binary stream, it is not text-oriented. Commented Aug 13, 2014 at 8:24

1 Answer 1

1

There are multiple mistakes: use of C-strings instead of std::string, no bound checks, e.t.c.:

BOOL ReadString(char *outstring)
{
    int *length; // !!!! length is not initialized, it may point to any address
    *length = sizeof(int);

    BYTE data;
    BYTE dataout[8192]={0};
    int index = 0;

    while(ReadByte(data)== TRUE) // !!!! No bound check. What if index will become more than 8192?
    {
        dataout[index++] = data;
    }
    memcpy(outstring, dataout, index);
    *length = index; // Hmm, length is not static it is automatic variable and will not keep the index between the calls

    return TRUE;
}

In main:

int main(void)
{
    //  Configs
    hPort = ConfigureSerialPort("COM1");
    if(hPort == NULL)
    {
        printf("Com port configuration failed\n");
        return -1;
    }


    char* cPTR; // !!!! Not initialized, points to any place in memory
    for(;;)
    {
      ReadString(cPTR); // !!!! cPTR not allocated, you pass the pointer to somwhere

      if(cPTR!=NULL)
        cout << "Scanned Data: " << cPTR << endl;
      else
        cout << "No data recieved." << endl;
    }
    ClosePort();
    return 0;
}

My proposal for read string function:

void ReadString(
  std::string& result,
  std::size_t& size)
{
  result.clear(); // If you need to keep track - don't clear

  BYTE byteIn;
  while (ReadByte(byteIn))
  {
    result.append(byteIn); // Maybe static_cast<char>(byteIn) required for BYTE to char
    size++;
  }
}

Now we can rewrite main as:

std::string buffer;
std::size_t length = 0;

while (true)
{
  ReadString(buffer, length);

  if(buffer.size())
    cout << "Scanned Data: " << buffer << endl;
  else
    cout << "No data recieved." << endl;

  // Some condition to break the cycle after 1Mb
  if (length > 1024 * 1024)
    break;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.