Hi, I am using Visual studio 2008, C++ MFC to do my programming for serial communication. I am having problem with my source code wehn i complied it. I have link the serial.cpp and serial.h file to my main program. In my main program, i just type Serial.Open(); to test my serial communication. I have initialise [CSerial Serial] in my .h(main program file).
When i run my main program, i get error C2512:"CSerial":no appropriate default constructor available. Hope someone can help me out. Thanks.
Serial.cpp
--------------
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <string.h>
#include "Serial.h"
#include <sstream>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerial::CSerial(const char *pszPortName)
: m_hSerialComm(INVALID_HANDLE_VALUE)
{
ASSERT(pszPortName);
m_pszPortName = new char[strlen(pszPortName)];
strcpy(m_pszPortName, pszPortName);
}
CSerial::~CSerial()
{
if(m_pszPortName)
delete[] m_pszPortName;
Close();
}
//////////////////////////////////////////////////////////////////////
// Name: Open
// Version: 1.0
// Return: HRESULT
// Comment: This function is used open a connection with a serial port.
// Uses non-overlapped i/o, and allows for reading & writing to the
// port.
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::Open()
{
HRESULT hResult;
m_hSerialComm = CreateFile((LPCTSTR)m_pszPortName, /* Port Name */
GENERIC_READ | GENERIC_WRITE, /* Desired Access */
0, /* Shared Mode */
NULL, /* Security */
OPEN_EXISTING, /* Creation Disposition */
0,
NULL); /* Non Overlapped */
if(m_hSerialComm == INVALID_HANDLE_VALUE)
{
unsigned long error = ::GetLastError();
hResult = E_FAIL;
}
else
hResult = S_OK;
return hResult;
}
//////////////////////////////////////////////////////////////////////
// Name: Close
// Version: 1.0
// Return: HRESULT
// Comment: This function is used to close the serial port connection
// Note: This function is called with the destructor
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::Close()
{
if(m_hSerialComm != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hSerialComm);
m_hSerialComm = INVALID_HANDLE_VALUE;
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// Name: ConfigPort
// Version: 1.0
// Parameter: dwBaudRate - This must be set to the baud rate of the
// serial port connection otherwise invalid reads occur.
// dwTimeOutInSec - Specifies the timeout for read and write of the serial
// port connection in seconds
// Return: HRESULT
// Comment: This function is used configure the serial port connection.
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::ConfigPort(DWORD dwBaudRate, DWORD dwTimeOutInSec)
{
if(!SetupComm(m_hSerialComm, 1024, 1024))
return E_FAIL;
DCB dcbConfig;
if(GetCommState(m_hSerialComm, &dcbConfig)) /* Configuring Serial Port Settings */
{
dcbConfig.BaudRate = dwBaudRate;
dcbConfig.ByteSize = 8;
dcbConfig.Parity = NOPARITY;
dcbConfig.StopBits = ONESTOPBIT;
dcbConfig.fBinary = TRUE;
dcbConfig.fParity = TRUE;
}
else
return E_FAIL;
if(!SetCommState(m_hSerialComm, &dcbConfig))
return E_FAIL;
COMMTIMEOUTS commTimeout;
if(GetCommTimeouts(m_hSerialComm, &commTimeout)) /* Configuring Read & Write Time Outs */
{
commTimeout.ReadIntervalTimeout = 1000*dwTimeOutInSec;
commTimeout.ReadTotalTimeoutConstant = 1000*dwTimeOutInSec;
commTimeout.ReadTotalTimeoutMultiplier = 0;
commTimeout.WriteTotalTimeoutConstant = 1000*dwTimeOutInSec;
commTimeout.WriteTotalTimeoutMultiplier = 0;
}
else
return E_FAIL;
if(SetCommTimeouts(m_hSerialComm, &commTimeout))
return S_OK;
else
return E_FAIL;
}
//////////////////////////////////////////////////////////////////////
// Name: Read
// Version: 1.0
// Parameter: ppszBuf - The buffer that will have the value that was
// read in from the serial port.
// dwSize - The size of the buffer
// Return: HRESULT
// Comment: This function sets an event that will be signalled if the
// any byte is buffered internally. Once this occurs, the function keeps
// reading multiple a single byte at a time until there is no more furthur
// byte to read from the input stream
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::Read(char **ppszBuf, DWORD &dwSize)
{
HRESULT hResult = S_OK;
std::stringbuf sb;
DWORD dwEventMask;
if(!SetCommMask(m_hSerialComm, EV_RXCHAR)) /* Setting Event Type */
return E_FAIL;
if(WaitCommEvent(m_hSerialComm, &dwEventMask, NULL)) /* Waiting For Event to Occur */
{
char szBuf;
DWORD dwIncommingReadSize;
do
{
if(ReadFile(m_hSerialComm, &szBuf, 1, &dwIncommingReadSize, NULL) != 0)
{
if(dwIncommingReadSize > 0)
{
dwSize += dwIncommingReadSize;
sb.sputn(&szBuf, dwIncommingReadSize);
}
}
else
{
unsigned long error = ::GetLastError();
hResult = E_FAIL;
break;
}
} while(dwIncommingReadSize > 0);
*ppszBuf = new char[dwSize];
strcpy(*ppszBuf, (sb.str()).c_str());
return hResult;
}
else
return E_FAIL;
}
//////////////////////////////////////////////////////////////////////
// Name: Write
// Version: 1.0
// Parameter: szBuf - The buffer holding the bytes to write to the serial
// port connection
// dwSize - The size of the buffer
// Return: HRESULT
// Comment: This function writes one byte at a time until all the bytes
// in the buffer is sent out
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::Write(const char *pszBuf, DWORD dwSize)
{
HRESULT hResult = S_OK;
ASSERT(pszBuf);
unsigned long dwNumberOfBytesSent = 0;
while(dwNumberOfBytesSent < dwSize)
{
unsigned long dwNumberOfBytesWritten;
if(WriteFile(m_hSerialComm, &pszBuf[dwNumberOfBytesSent], 1, &dwNumberOfBytesWritten, NULL) != 0)
{
if(dwNumberOfBytesWritten > 0)
++dwNumberOfBytesSent;
else
{
unsigned long error = ::GetLastError();
hResult = E_FAIL;
break;
}
}
else
{
unsigned long error = ::GetLastError();
hResult = E_FAIL;
break;
}
}
return hResult;
}
//////////////////////////////////////////////////////////////////////
// Name: Flush
// Version: 1.0
// Parameter: dwFlag - The flag specifying if the input/output buffer
// to be flushed
// Return: HRESULT
// Comment: This function is flushes the specfied buffer
// Note: By default, both the input and output buffers are flushed
//////////////////////////////////////////////////////////////////////
HRESULT CSerial::Flush(DWORD dwFlag)
{
if(PurgeComm(m_hSerialComm, dwFlag))
return S_OK;
else
return E_FAIL;
}
Serial.h
-----------
// Serial.h: interface for the CSerial class.
//
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#if !defined(AFX_Serial_H__D1CAB621_DF4B_4729_82AB_31D5B9EFE8A9__INCLUDED_)
#define AFX_Serial_H__D1CAB621_DF4B_4729_82AB_31D5B9EFE8A9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////////////////////////
// Name: CSerial
// Version: 1.0
// Comment: This class is responsible for provide I/O operation with
// a serial port. It is implemented with Synchronous I/O viz. both
// input and output operations block. Both read and write operations
// are supported.
//////////////////////////////////////////////////////////////////////
class CSerial
{
public:
HRESULT Flush(DWORD dwFlag = PURGE_TXCLEAR | PURGE_RXCLEAR);
HRESULT Write(const char *pszBuf, DWORD dwSize);
HRESULT Read(char **ppszBuf, DWORD &dwSize);
HRESULT ConfigPort(DWORD dwBaudRate = CBR_19200, DWORD dwTimeOutInSec = 5);
HRESULT Close();
HRESULT Open();
CSerial(const char *pszPortName);
virtual ~CSerial();
private:
char *m_pszPortName;
HANDLE m_hSerialComm;
};
#endif // !defined(AFX_Serial_H__D1CAB621_DF4B_4729_82AB_31D5B9EFE8A9__INCLUDED_)