Click here to Skip to main content
6,635,885 members and growing! (22,712 online)
Email Password   helpLost your password?
Languages » C++ / CLI » P/Invoke     Intermediate

How to open a serial COM port in Managed C++

By Albert Pascual

How to open a Serial COM port using Managed C++ and loading unmanaged DLLs
C++/CLI, VC6, VC7, .NET, Win2K, WinXP, Visual Studio, MFC, Dev
Posted:16 Apr 2002
Views:207,189
Bookmarked:50 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
55 votes for this article.
Popularity: 7.63 Rating: 4.38 out of 5

1
1 vote, 4.2%
2
2 votes, 8.3%
3
4 votes, 16.7%
4
17 votes, 70.8%
5

Introduction

Many days ago, I was looking for a class in managed C++ that gives me access to the COM port. I was surprised I couldn't find anything to use. There were many classes to use for sockets and files, but none for COM ports.

I tried to use System::IO::File without any success. Actually File::Open gave me an exception. So I went ahead and created a class to handle serial COM ports. Please note I am using DllImport to import the kernel32.dll 

// Header File

__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 );

}

Also note that I am creating a new namespace to use the imported functions from kernel32.dll

This is the cpp file:

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();
}

To use it:

CSerialPort * pSerial = new CSerialPort;

pSerial->Open(S"COM2:");
Console::WriteLine(pSerial->Read());

We open COM port 2 and we wait to read a LINE with \r\n or \n. If you waiting for bytes you need to change m_MyStreamReader->ReadLine() to m_MyStreamReader->Read().

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Albert Pascual


Member
Al is just another Software Engineer working in C++, ASp.NET and C#. Enjoys snowboarding in Big Bear, and wait patiently for his daughters to be old enough to write code and snowboard.

Al is a Microsoft ASP.NET MVP

Blog
Occupation: Web Developer
Location: United States United States

Other popular C++ / CLI articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 49 (Total in Forum: 49) (Refresh)FirstPrevNext
GeneralI cannot SetCommState to return true. Pinmembernetlogging6:13 4 Apr '08  
QuestionException by FileStream Pinmemberstrizi1:16 2 Nov '07  
QuestionRe: Exception by FileStream Pinmembernetlogging6:46 4 Apr '08  
QuestionSample code Pinmemberstrizi1:14 2 Nov '07  
GeneralHi Pinmembertemikasali21:17 6 Aug '07  
Generalcode problem! PinmemberNenica14:15 16 Jun '04  
GeneralRe: code problem! PinmemberHristoBojkov23:18 20 Apr '05  
GeneralWin32 Application PinmemberNenica11:28 18 Feb '04  
GeneralRe: Win32 Application Pinmembersurajt10:00 14 May '04  
GeneralRe: Win32 Application PinmemberNenica14:12 16 Jun '04  
GeneralRe: Win32 Application PinmemberSharingan_Rasengan19:05 10 Jul '06  
GeneralRe: Win32 Application PinmemberSharingan_Rasengan19:05 10 Jul '06  
GeneralRe: Win32 Application Pinmembermertadin23:19 18 Jul '06  
GeneralRe: Win32 Application Pinmemberuptonryan21:46 19 Nov '06  
GeneralRe: Win32 Application PinmemberYaoTown19:08 11 Mar '08  
QuestionRe: Win32 Application Pinmembernetlogging6:47 4 Apr '08  
GeneralProject Files? PinsussUwe Komoss14:43 6 Aug '03  
GeneralWhat is the keywords __gc ? Pinmembergertano3:45 13 May '03  
GeneralRe: What is the keywords __gc ? PinmemberAlbert Pascual6:43 13 May '03  
GeneralRe: What is the keywords __gc ? Pinmembergertano11:09 13 May '03  
GeneralRe: What is the keywords __gc ? PinmemberAlbert Pascual13:53 13 May '03  
GeneralRe: What is the keywords __gc ? Pinmemberwadegiles7:13 6 Jul '05  
GeneralSerial comms sample code PinsussColin Bowdery2:26 3 Apr '03  
GeneralRe: Serial comms sample code Pinmemberwadegiles6:58 6 Jul '05  
Generalusing this class with visual c++ PinmemberSFH6:29 2 Apr '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 16 Apr 2002
Editor: Chris Maunder
Copyright 2002 by Albert Pascual
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project