I need to write a small program which collects (20-36 string) data from several com (serial ports) and sends them out on one. For example com2,3,4 to com1.
It should be on Windows Xp workstation. (It is possible that I will do it later on linux, it seems to me simpler to use /dev/ttyS0, but my boss prefers MS)

I find several several examples where I can define my own classes, header files for opening serial port.
I tried the attached one. It defines a CSerialPort class for functions to open and read from serial port.
There is also a header file cserial.h. (attachements)
There is a note:
I am using DllImport to import the kernel32.dll for this header file.

I tried to use the attached cserial.h header file. But I get several errors while compile:
expected constructor destructor before class
expected , or ; before class

... more in serial.jpg attached

Note:
Maybe I am trying to use those source codes totally the wrong way, sorry if so.
Any suggestion that can align me in to the right direction will help.
If somebody knows better example codes for serial programming (for WinXp, DevC++), please post it for me.

Attachments
CSerialPort::CSerialPort(void)
{
}

bool CSerialPort::Open( char *szComPort)
{
    int handle;
            
    handle = MyKernel::CreateFile(
        szComPort,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_ALWAYS,
        FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
        NULL);

    try
    {
        IntPtr    pCom(handle);
        m_MyFileStream = new FileStream(pCom, 
                                        FileAccess::ReadWrite, 
                                        true, 1000, true);        
    }

    catch (Exception  * e ) {
        Console::WriteLine(e->ToString());
          return false;
      }

    
    DCB    * CommSettings = new DCB();
    CommSettings->DCBlength = sizeof(CommSettings);
    CommSettings->BaudRate  = 38400;
    CommSettings->ByteSize  = 8;
    CommSettings->Parity    = 0;
    CommSettings->StopBits    = 1;

    MyKernel::SetCommState(m_MyFileStream->get_Handle(), 
                           CommSettings);
    

    try
    {
        m_MyStreamReader = new StreamReader(m_MyFileStream);
    }

    catch (Exception  * e ) {
        Console::WriteLine(e->ToString());
          return false;
      }

    if ( m_MyFileStream->get_CanWrite() )
    {
        try
        {
            m_MyStreamWriter = new StreamWriter(m_MyFileStream);
        }

        catch (Exception  * e ) {
            Console::WriteLine(e->ToString());
            return false;
        }
    }

    return true;
}

void CSerialPort::Write(String __gc * buf)
{
    try
    {
        m_MyStreamWriter->Write(buf);
        m_MyStreamWriter->Flush();    
        
    }

    catch (Exception  * e ) {
        Console::WriteLine(e->ToString());    
      }
}

String  * CSerialPort::Read()
{
    String    *buf;
    
    buf = m_MyStreamReader->ReadLine();

    return (buf);
}

void CSerialPort::Close()
{
    m_MyStreamWriter->Close();
    m_MyStreamReader->Close();
    m_MyFileStream->Close();
}
__gc class CSerialPort
{
public:
    CSerialPort(void);
    __nogc struct DCB
    {
        int DCBlength;
        int BaudRate;
        int fBinary;
        int fParity;
        int fOutxCtsFlow;
        int fOutxDsrFlow;
        int fDtrControl;
        int fDsrSensitivity;
        int fTXContinueOnXoff;
        int fOutX;
        int fInX;
        int fErrorChar;
        int fNull;
        int fRtsControl;
        int fAbortOnError;
        int fDummy2;
        unsigned short wReserved;
        unsigned short XonLim;
        unsigned char ByteSize;    //byte

        unsigned char Parity; // byte

        unsigned char StopBits;    //byte

        char XonChar;
        char XoffChar;
        char ErrorChar;
        char EofChar;
        char EvtChar;
        unsigned short wReserved1;
    };

    bool    Open( char *szComPort);
    void    Write(String __gc * buf);
    String  *Read();
    void    Close();

private:    
    FileStream    * m_MyFileStream;
    StreamWriter * m_MyStreamWriter;
    StreamReader * m_MyStreamReader;
    
    static long GENERIC_READ  = 0x80000000L;
    static long GENERIC_WRITE = 0x40000000L;

    static int OPEN_ALWAYS = 4;

    static int FILE_FLAG_NO_BUFFERING = 0x20000000;
    static int FILE_FLAG_OVERLAPPED   = 0x40000000;

};

namespace MyKernel
{
[DllImport("kernel32.dll")]
extern bool SetCommState(System::IntPtr hFile, CSerialPort::DCB * lpDBC);
[DllImport("kernel32.dll")]
extern int CreateFile( char * lpFileName , int dwDesiredAccess, int dwShareMode,
  IntPtr lpSecurityAttributes, int dwCreationDisposition,
  int dwFlagsAndAttributes, IntPtr hTemplateFile );

}
serial.JPG 46.09 KB

I find a simpler one:

#include <stdio.h>
#include <dos.h>

void main(void)
{
 unsigned int far *ptraddr;  /* Pointer to location of Port Addresses */
 unsigned int address;       /* Address of Port */
 int a;

 ptraddr=(unsigned int far *)0x00000400;

 for (a = 0; a <  4; a++)
   {
    address = *ptraddr;
    if (address == 0)
                printf("No port found for COM%d \n",a+1);
    else
                printf("Address assigned to COM%d is %Xh\n",a+1,address);
    *ptraddr++;
   }
}

But I have troubles with the far variable.

It seems to me that this is a direct access to the serial port for example on address 3F8.
What is this usigned int far *ptraddr?

You have to be very careful about the code you get off the net because a lot of it is written for ancient 16-bit compilers on MS-DOS version 6.X and earlier operating systems. You might as well scrap that second code you found because it won't work on modern 32-bit compilers or MS-Windows.

As for the first program you posted, I don't know what compiler/os that was written for because it contains a lot of stuff I've never encountered before. So you might as well scrap that code too.

For MS-Windows, all you need to do is use the communications functions that are described in Communications Resources. You will want to create a thread for each port you want to monitor and do the reading from there.

I don´t want to discard the MS environment, but for now it is easier to me to go on with the "Linux's file descriptors":

/*
     * 'open_port()' - Open serial port 1.
     *
     * Returns the file descriptor on success or -1 on error.
     */

    int
    open_port(void)
    {
      int fd; /* File descriptor for the port */


      fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd == -1)
      {
       /*
	* Could not open the port.
	*/

	perror("open_port: Unable to open /dev/ttyS0 - ");
      }
      else
	fcntl(fd, F_SETFL, 0);

// and write(); read(); for data processing

      return (fd);
    }

It is very simple to use the serial port on this OS.

I need to test (generate) the outgoing character strings mainly, for now. (the device wich receives it on the other side is more importan to me). I will search for the trick how to work with serial ports on the MS, but a litle later (when I will have enough time)
This is different on this documentation:
http://www.easysw.com/~mike/serial/serial.html

In this documentation I find really fast what I need.
Thanks, I understand that there are lot of scrap codes on the internet.

This article has been dead for over six months. Start a new discussion instead.