{
CSerialPort *port=(CSerialPort*)pParam;
port->m_bThreadAlive=true;
DWORD BytesTransfered=0;
DWORD Event=0;
DWORD CommEvent=0;
DWORD dwError=0;
COMSTAT comstat;
BOOL bResult=true;
DWORD error=0;
if(port->m_hComm)
{
//PurgeComm(port->m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
ClearCommError(port->m_hComm,&error,&comstat);
SetCommMask(port->m_hComm,port->m_dwCommEvents);//设置通信事件
for(;;)
{
bResult=WaitCommEvent(port->m_hComm,&Event,&port->m_ov);
if(!bResult)
{
switch(dwError=GetLastError())
{
case ERROR_IO_PENDING:
break;//this is a normal value if there are no bytes to read at the port.do nonthing and continue
case 87:
break;
default:
{
port->ProcessErrorMessage("WaitCommEvent");
break;
}
}
}
else
{
bResult=ClearCommError(port->m_hComm,&dwError,&comstat);
if(comstat.cbInQue==0)
continue;
}
Event=WaitForMultipleObjects(3,port->m_hEventArray,FALSE,INFINITE);//应该是阻塞在这 现在返回了句柄无效???
switch(Event)
{
case 0:
{
AfxMessageBox("shut Event");
port->m_bThreadAlive=false;
AfxEndThread(100);// 杀死线程
break;
}
case 1://read event
{
AfxMessageBox("read Event");
GetCommMask(port->m_hComm,&CommEvent);
if(CommEvent&EV_CTS)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_CTS_DETECTED,(WPARAM)0,(LPARAM)port->m_nPortNr);
if(CommEvent&EV_RXFLAG)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RXFLAG_DETECTED,(WPARAM)0,(LPARAM)port->m_nPortNr);
if(CommEvent&EV_BREAK)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_BREAK_DETECTED,(WPARAM)0,(LPARAM)port->m_nPortNr);
if(CommEvent&EV_ERR)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_ERR_DETECTED,(WPARAM)0,(LPARAM)port->m_nPortNr);
if(CommEvent&EV_RING)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RING_DETECTED,(WPARAM)0,(LPARAM)port->m_nPortNr);
if(CommEvent&EV_RXCHAR)
ReceiveChar(port,comstat);
break;
}
case 2://write event
{
AfxMessageBox("write Event");
WriteChar(port);
break;
}
default:
{
CString error;
error.Format("%d",GetLastError());
AfxMessageBox("WaitForMultipleObjects出错\n"+error);
port->m_bThreadAlive=false;
AfxEndThread(100);// 杀死线程
break;
return -1;
}
}
}
}
return 0;
}
问题在WaitForMultipleObjects(3,port->m_hEventArray,FALSE,INFINITE);//调用一直出错,打印错误信息是句柄无效
然后我单个句柄进行调用,结果是每一个的无效???按理说应该是阻塞在这。。。。
请求高手指点?????急???
8 个解决方案
#1
线程定义成 static 型了么?
#2
1.在CSerialPort类里面 线程好像没有定义成static的
2. 为什么要定义成STATIC的了?
2. 为什么要定义成STATIC的了?
#3
肯定是你自己改动什么地方改错了,如果你一点不改拿过来用不可能有这个错误
#5
BOOL CSerialPort::InitComm(CWnd* pPortOwner,
UINT portnr,
UINT baud,
char parity,
UINT databits,
UINT stopbits,
DWORD dwCommEvents,
UINT writebuffersize)
{
assert(portnr>0 && portnr<5);
assert(pPortOwner!=NULL);
//if the thread is alive :kill
if(m_bThreadAlive)
{
do
{
SetEvent(m_hShutdownEvent);
}while(m_bThreadAlive);
} TRACE("Thread end!\n");
//creat events
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
else m_ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//人工重置事件
if(m_hWriteEvent!=NULL)
{
ResetEvent(m_hWriteEvent);
}
else m_hWriteEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//都是属于没有信号状态
if(m_hShutdownEvent!=NULL)
ResetEvent(m_hShutdownEvent);
else m_hShutdownEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hEventArray[0]=m_hShutdownEvent;//highest priority
m_hEventArray[1]=m_ov.hEvent;
m_hEventArray[2]=m_hWriteEvent;
//init critical section
InitializeCriticalSection(&this->m_csCommunicationSync);
//set buffersize for writting and save the ower
m_pOwner=pPortOwner;
if(m_szWriteBuffer!=NULL)
{
delete [] m_szWriteBuffer;
}
m_szWriteBuffer=new char[writebuffersize];
m_nPortNr=portnr;
m_nWriteBufferSize=writebuffersize;
m_dwCommEvents=dwCommEvents;
BOOL bResult=false;
char *szPort=new char[50];
char *szBaud=new char[50];
EnterCriticalSection(&this->m_csCommunicationSync);
//进入临界区
// if the port is already opened: close it
if(m_hComm!=NULL)
{
CloseHandle(m_hComm);
m_hComm=NULL;
}
// prepare port strings
sprintf(szPort,"COM%d",portnr);
sprintf(szBaud,"baud=%d parity=%c data=%d stop=%d",baud,parity,databits,stopbits);
// get a handle to the port
m_hComm=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,
0,//端口只能独享
NULL,//默认的安全属性
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);//template must be 0 for comm devices
if(m_hComm==INVALID_HANDLE_VALUE)
{
delete [] szPort;
delete [] szBaud;
return false;
}
if(!SetupComm(m_hComm,1024,512))
{
AfxMessageBox("设置缓冲区失败");
return false;
}
PurgeComm(m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//set timeout values
m_CommTimeouts.ReadIntervalTimeout=MAXDWORD;
m_CommTimeouts.ReadTotalTimeoutMultiplier=0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
m_CommTimeouts.WriteTotalTimeoutConstant=5000;
if(SetCommTimeouts(m_hComm,&m_CommTimeouts))
{
if(SetCommMask(m_hComm,dwCommEvents))
{
if(GetCommState(m_hComm,&m_dcb))
{
m_dcb.fDtrControl=RTS_CONTROL_ENABLE;// set RTS bit high!
m_dcb.fBinary=true;
m_dcb.EofChar=0x1a;
m_dcb.DCBlength=sizeof(DCB);
m_dcb.fInX=true;
m_dcb.fOutX=true;
m_dcb.XoffChar=XOFF;
m_dcb.XonChar=XON;
m_dcb.XoffLim=256;
m_dcb.XonLim=256;
if(BuildCommDCB(szBaud,&m_dcb))
{
if(SetCommState(m_hComm,&m_dcb));
else
ProcessErrorMessage("SetCommState");
}
else ProcessErrorMessage("BuildCommDCB");
}
else ProcessErrorMessage("GetCommState()");
}
else ProcessErrorMessage("SetCommMask()");
}
else ProcessErrorMessage("SetCommTimeouts()");
delete [] szPort;
delete [] szBaud;
LeaveCriticalSection(&m_csCommunicationSync);
TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
return true;
}
这是我的初始化端口页面,下午测试是写事件对象无效!!!!
???
UINT portnr,
UINT baud,
char parity,
UINT databits,
UINT stopbits,
DWORD dwCommEvents,
UINT writebuffersize)
{
assert(portnr>0 && portnr<5);
assert(pPortOwner!=NULL);
//if the thread is alive :kill
if(m_bThreadAlive)
{
do
{
SetEvent(m_hShutdownEvent);
}while(m_bThreadAlive);
} TRACE("Thread end!\n");
//creat events
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
else m_ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//人工重置事件
if(m_hWriteEvent!=NULL)
{
ResetEvent(m_hWriteEvent);
}
else m_hWriteEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//都是属于没有信号状态
if(m_hShutdownEvent!=NULL)
ResetEvent(m_hShutdownEvent);
else m_hShutdownEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hEventArray[0]=m_hShutdownEvent;//highest priority
m_hEventArray[1]=m_ov.hEvent;
m_hEventArray[2]=m_hWriteEvent;
//init critical section
InitializeCriticalSection(&this->m_csCommunicationSync);
//set buffersize for writting and save the ower
m_pOwner=pPortOwner;
if(m_szWriteBuffer!=NULL)
{
delete [] m_szWriteBuffer;
}
m_szWriteBuffer=new char[writebuffersize];
m_nPortNr=portnr;
m_nWriteBufferSize=writebuffersize;
m_dwCommEvents=dwCommEvents;
BOOL bResult=false;
char *szPort=new char[50];
char *szBaud=new char[50];
EnterCriticalSection(&this->m_csCommunicationSync);
//进入临界区
// if the port is already opened: close it
if(m_hComm!=NULL)
{
CloseHandle(m_hComm);
m_hComm=NULL;
}
// prepare port strings
sprintf(szPort,"COM%d",portnr);
sprintf(szBaud,"baud=%d parity=%c data=%d stop=%d",baud,parity,databits,stopbits);
// get a handle to the port
m_hComm=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,
0,//端口只能独享
NULL,//默认的安全属性
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);//template must be 0 for comm devices
if(m_hComm==INVALID_HANDLE_VALUE)
{
delete [] szPort;
delete [] szBaud;
return false;
}
if(!SetupComm(m_hComm,1024,512))
{
AfxMessageBox("设置缓冲区失败");
return false;
}
PurgeComm(m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//set timeout values
m_CommTimeouts.ReadIntervalTimeout=MAXDWORD;
m_CommTimeouts.ReadTotalTimeoutMultiplier=0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
m_CommTimeouts.WriteTotalTimeoutConstant=5000;
if(SetCommTimeouts(m_hComm,&m_CommTimeouts))
{
if(SetCommMask(m_hComm,dwCommEvents))
{
if(GetCommState(m_hComm,&m_dcb))
{
m_dcb.fDtrControl=RTS_CONTROL_ENABLE;// set RTS bit high!
m_dcb.fBinary=true;
m_dcb.EofChar=0x1a;
m_dcb.DCBlength=sizeof(DCB);
m_dcb.fInX=true;
m_dcb.fOutX=true;
m_dcb.XoffChar=XOFF;
m_dcb.XonChar=XON;
m_dcb.XoffLim=256;
m_dcb.XonLim=256;
if(BuildCommDCB(szBaud,&m_dcb))
{
if(SetCommState(m_hComm,&m_dcb));
else
ProcessErrorMessage("SetCommState");
}
else ProcessErrorMessage("BuildCommDCB");
}
else ProcessErrorMessage("GetCommState()");
}
else ProcessErrorMessage("SetCommMask()");
}
else ProcessErrorMessage("SetCommTimeouts()");
delete [] szPort;
delete [] szBaud;
LeaveCriticalSection(&m_csCommunicationSync);
TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
return true;
}
这是我的初始化端口页面,下午测试是写事件对象无效!!!!
???
#6
呵呵。。。不是有很好的已经写好的,干嘛不拿来用呀。
#7
CSerialPort有V1.19那个版本的吗,
#8
现在有更高的版本了。
#1
线程定义成 static 型了么?
#2
1.在CSerialPort类里面 线程好像没有定义成static的
2. 为什么要定义成STATIC的了?
2. 为什么要定义成STATIC的了?
#3
肯定是你自己改动什么地方改错了,如果你一点不改拿过来用不可能有这个错误
#4
#5
BOOL CSerialPort::InitComm(CWnd* pPortOwner,
UINT portnr,
UINT baud,
char parity,
UINT databits,
UINT stopbits,
DWORD dwCommEvents,
UINT writebuffersize)
{
assert(portnr>0 && portnr<5);
assert(pPortOwner!=NULL);
//if the thread is alive :kill
if(m_bThreadAlive)
{
do
{
SetEvent(m_hShutdownEvent);
}while(m_bThreadAlive);
} TRACE("Thread end!\n");
//creat events
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
else m_ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//人工重置事件
if(m_hWriteEvent!=NULL)
{
ResetEvent(m_hWriteEvent);
}
else m_hWriteEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//都是属于没有信号状态
if(m_hShutdownEvent!=NULL)
ResetEvent(m_hShutdownEvent);
else m_hShutdownEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hEventArray[0]=m_hShutdownEvent;//highest priority
m_hEventArray[1]=m_ov.hEvent;
m_hEventArray[2]=m_hWriteEvent;
//init critical section
InitializeCriticalSection(&this->m_csCommunicationSync);
//set buffersize for writting and save the ower
m_pOwner=pPortOwner;
if(m_szWriteBuffer!=NULL)
{
delete [] m_szWriteBuffer;
}
m_szWriteBuffer=new char[writebuffersize];
m_nPortNr=portnr;
m_nWriteBufferSize=writebuffersize;
m_dwCommEvents=dwCommEvents;
BOOL bResult=false;
char *szPort=new char[50];
char *szBaud=new char[50];
EnterCriticalSection(&this->m_csCommunicationSync);
//进入临界区
// if the port is already opened: close it
if(m_hComm!=NULL)
{
CloseHandle(m_hComm);
m_hComm=NULL;
}
// prepare port strings
sprintf(szPort,"COM%d",portnr);
sprintf(szBaud,"baud=%d parity=%c data=%d stop=%d",baud,parity,databits,stopbits);
// get a handle to the port
m_hComm=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,
0,//端口只能独享
NULL,//默认的安全属性
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);//template must be 0 for comm devices
if(m_hComm==INVALID_HANDLE_VALUE)
{
delete [] szPort;
delete [] szBaud;
return false;
}
if(!SetupComm(m_hComm,1024,512))
{
AfxMessageBox("设置缓冲区失败");
return false;
}
PurgeComm(m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//set timeout values
m_CommTimeouts.ReadIntervalTimeout=MAXDWORD;
m_CommTimeouts.ReadTotalTimeoutMultiplier=0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
m_CommTimeouts.WriteTotalTimeoutConstant=5000;
if(SetCommTimeouts(m_hComm,&m_CommTimeouts))
{
if(SetCommMask(m_hComm,dwCommEvents))
{
if(GetCommState(m_hComm,&m_dcb))
{
m_dcb.fDtrControl=RTS_CONTROL_ENABLE;// set RTS bit high!
m_dcb.fBinary=true;
m_dcb.EofChar=0x1a;
m_dcb.DCBlength=sizeof(DCB);
m_dcb.fInX=true;
m_dcb.fOutX=true;
m_dcb.XoffChar=XOFF;
m_dcb.XonChar=XON;
m_dcb.XoffLim=256;
m_dcb.XonLim=256;
if(BuildCommDCB(szBaud,&m_dcb))
{
if(SetCommState(m_hComm,&m_dcb));
else
ProcessErrorMessage("SetCommState");
}
else ProcessErrorMessage("BuildCommDCB");
}
else ProcessErrorMessage("GetCommState()");
}
else ProcessErrorMessage("SetCommMask()");
}
else ProcessErrorMessage("SetCommTimeouts()");
delete [] szPort;
delete [] szBaud;
LeaveCriticalSection(&m_csCommunicationSync);
TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
return true;
}
这是我的初始化端口页面,下午测试是写事件对象无效!!!!
???
UINT portnr,
UINT baud,
char parity,
UINT databits,
UINT stopbits,
DWORD dwCommEvents,
UINT writebuffersize)
{
assert(portnr>0 && portnr<5);
assert(pPortOwner!=NULL);
//if the thread is alive :kill
if(m_bThreadAlive)
{
do
{
SetEvent(m_hShutdownEvent);
}while(m_bThreadAlive);
} TRACE("Thread end!\n");
//creat events
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
else m_ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//人工重置事件
if(m_hWriteEvent!=NULL)
{
ResetEvent(m_hWriteEvent);
}
else m_hWriteEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//都是属于没有信号状态
if(m_hShutdownEvent!=NULL)
ResetEvent(m_hShutdownEvent);
else m_hShutdownEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hEventArray[0]=m_hShutdownEvent;//highest priority
m_hEventArray[1]=m_ov.hEvent;
m_hEventArray[2]=m_hWriteEvent;
//init critical section
InitializeCriticalSection(&this->m_csCommunicationSync);
//set buffersize for writting and save the ower
m_pOwner=pPortOwner;
if(m_szWriteBuffer!=NULL)
{
delete [] m_szWriteBuffer;
}
m_szWriteBuffer=new char[writebuffersize];
m_nPortNr=portnr;
m_nWriteBufferSize=writebuffersize;
m_dwCommEvents=dwCommEvents;
BOOL bResult=false;
char *szPort=new char[50];
char *szBaud=new char[50];
EnterCriticalSection(&this->m_csCommunicationSync);
//进入临界区
// if the port is already opened: close it
if(m_hComm!=NULL)
{
CloseHandle(m_hComm);
m_hComm=NULL;
}
// prepare port strings
sprintf(szPort,"COM%d",portnr);
sprintf(szBaud,"baud=%d parity=%c data=%d stop=%d",baud,parity,databits,stopbits);
// get a handle to the port
m_hComm=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,
0,//端口只能独享
NULL,//默认的安全属性
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);//template must be 0 for comm devices
if(m_hComm==INVALID_HANDLE_VALUE)
{
delete [] szPort;
delete [] szBaud;
return false;
}
if(!SetupComm(m_hComm,1024,512))
{
AfxMessageBox("设置缓冲区失败");
return false;
}
PurgeComm(m_hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//set timeout values
m_CommTimeouts.ReadIntervalTimeout=MAXDWORD;
m_CommTimeouts.ReadTotalTimeoutMultiplier=0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
m_CommTimeouts.WriteTotalTimeoutConstant=5000;
if(SetCommTimeouts(m_hComm,&m_CommTimeouts))
{
if(SetCommMask(m_hComm,dwCommEvents))
{
if(GetCommState(m_hComm,&m_dcb))
{
m_dcb.fDtrControl=RTS_CONTROL_ENABLE;// set RTS bit high!
m_dcb.fBinary=true;
m_dcb.EofChar=0x1a;
m_dcb.DCBlength=sizeof(DCB);
m_dcb.fInX=true;
m_dcb.fOutX=true;
m_dcb.XoffChar=XOFF;
m_dcb.XonChar=XON;
m_dcb.XoffLim=256;
m_dcb.XonLim=256;
if(BuildCommDCB(szBaud,&m_dcb))
{
if(SetCommState(m_hComm,&m_dcb));
else
ProcessErrorMessage("SetCommState");
}
else ProcessErrorMessage("BuildCommDCB");
}
else ProcessErrorMessage("GetCommState()");
}
else ProcessErrorMessage("SetCommMask()");
}
else ProcessErrorMessage("SetCommTimeouts()");
delete [] szPort;
delete [] szBaud;
LeaveCriticalSection(&m_csCommunicationSync);
TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
return true;
}
这是我的初始化端口页面,下午测试是写事件对象无效!!!!
???
#6
呵呵。。。不是有很好的已经写好的,干嘛不拿来用呀。
#7
CSerialPort有V1.19那个版本的吗,
#8
现在有更高的版本了。