重写串口通信从C ++到C# [英] Rewrite serial port communicationf rom C++ to C#
问题描述
void some func() ...)
{
* hDev = CreateFile(PortNameUNC,GENERIC_READ | GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(* hDev == INVALID_HANDLE_VALUE)返回false;
DCB * dcb = new DCB;
memset(dcb,0x00,sizeof(DCB));
dcb-> DCBlength = sizeof(DCB);
dcb-> BaudRate = BaudRate;
dcb-> Parity = Parity;
dcb-> StopBits = StopBits;
dcb-> ByteSize = ByteSize;
dcb-> fBinary = TRUE;
dcb-> fDsrSensitivity = 0;
dcb-> fDtrControl =(DTR?DTR_CONTROL_ENABLE:DTR_CONTROL_DISABLE);
dcb-> fRtsControl =(RTS?RTS_CONTROL_ENABLE:RTS_CONTROL_DISABLE);
dcb-> fOutxCtsFlow =(CTS?1:0);
dcb-> fOutxDsrFlow =(DSR?1:0);
dcb-> fOutX =(XonnXoff?1:0);
dcb-> fInX = 0;
if(!SetCommState(* hDev,dcb))
{
delete dcb;
CloseHandle(* hDev);
* hDev = INVALID_HANDLE_VALUE;
return false;
}
if(!SetTimeOut(readTimeOut,ReadIntervalTimeout)||!Reset())
{
CloseHandle(* hDev);
* hDev = INVALID_HANDLE_VALUE;
return false;
}
}
bool serial :: SetTimeOut(DWORD readTimeOut,DWORD ReadIntervalTimeout)
{
COMMTIMEOUTS * timeouts = new COMMTIMEOUTS;
memset(timeouts,0,sizeof(COMMTIMEOUTS));
timeouts-> ReadIntervalTimeout = ReadIntervalTimeout;
timeouts-> ReadTotalTimeoutMultiplier = 5;
timeouts-> ReadTotalTimeoutConstant = readTimeOut; // ...
timeouts-> WriteTotalTimeoutConstant = 0; //
timeouts-> WriteTotalTimeoutMultiplier = 2 * BaudRate / 8;
const bool ret = SetCommTimeouts(* hDev,timeouts)!= FALSE;
删除超时;
m_currentTimeOut = readTimeOut;
return ret;
}
这是我的C#映射:
public SerialPortHASP(string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits,bool dtr,bool rts,bool xonxoff)
{
m_port = new SerialPort(portName,baudRate,parity,dataBits,stopBits);
//只是用户输入的存储参数
m_portName = portName;
m_baudRate = baudRate;
m_parity = parity;
m_dataBits = dataBits;
m_stopBits = stopBits;
m_xonxoff = xonxoff;
m_dtr = dtr;
m_rts = rts;
//设置XonXoff(如果设置)
if(xonxoff)
m_port.Handshake = Handshake.XOnXOff;
//设置DTR / RTS
m_port.DtrEnable = dtr;
m_port.RtsEnable = rts;
m_port.ReadTimeout = 500; //或一些其他值
m_port.WriteTimeout = 500;
//打开通信端口
m_port.Open();
}
我需要实现一些其他读写操作我可以测试,如果我的映射是正确的,所以这是为什么我想双重检查如果我采取正确的方法映射上述代码到C#?或者我应该使用PInvoke呼叫获取此路由吗?还是尝试我目前的方法?感谢
PS。你可以看到这种方式我不能复制C ++调用允许的所有参数
初始化:
m_port.DataReceived + = _serial_DataReceived;
事件从端口获取数据。需要异步工作。
和
void _serial_DataReceived对象发送方,SerialDataReceivedEventArgs e)
{
int _len = _serial.BytesToRead;
byte [] _out = new byte [_len];
_serial.Read(_out,0,_len);
}
I want to know if I correctly mapped this C++ code which establishes serial port communication to C#.
void some func(...)
{
*hDev = CreateFile(PortNameUNC, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(*hDev == INVALID_HANDLE_VALUE) return false ;
DCB *dcb = new DCB ;
memset(dcb, 0x00, sizeof(DCB)) ;
dcb->DCBlength = sizeof(DCB);
dcb->BaudRate = BaudRate;
dcb->Parity = Parity;
dcb->StopBits = StopBits;
dcb->ByteSize = ByteSize;
dcb->fBinary = TRUE;
dcb->fDsrSensitivity = 0;
dcb->fDtrControl = (DTR ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE) ;
dcb->fRtsControl = (RTS ? RTS_CONTROL_ENABLE : RTS_CONTROL_DISABLE) ;
dcb->fOutxCtsFlow = (CTS ? 1 : 0) ;
dcb->fOutxDsrFlow = (DSR ? 1 : 0) ;
dcb->fOutX = (XonnXoff ? 1 : 0) ;
dcb->fInX = 0 ;
if(!SetCommState(*hDev, dcb))
{
delete dcb ;
CloseHandle(*hDev) ;
*hDev = INVALID_HANDLE_VALUE ;
return false;
}
if(!SetTimeOut(readTimeOut, ReadIntervalTimeout) || !Reset())
{
CloseHandle(*hDev) ;
*hDev = INVALID_HANDLE_VALUE ;
return false;
}
}
bool serial::SetTimeOut(DWORD readTimeOut, DWORD ReadIntervalTimeout)
{
COMMTIMEOUTS *timeouts = new COMMTIMEOUTS ;
memset(timeouts, 0, sizeof(COMMTIMEOUTS)) ;
timeouts->ReadIntervalTimeout = ReadIntervalTimeout ;
timeouts->ReadTotalTimeoutMultiplier = 5 ;
timeouts->ReadTotalTimeoutConstant = readTimeOut ; //...
timeouts->WriteTotalTimeoutConstant = 0 ; //
timeouts->WriteTotalTimeoutMultiplier = 2*BaudRate/8 ;
const bool ret = SetCommTimeouts(*hDev, timeouts) != FALSE ;
delete timeouts ;
m_currentTimeOut = readTimeOut ;
return ret ;
}
This is my C# mapping:
public SerialPortHASP(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, bool dtr, bool rts, bool xonxoff)
{
m_port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
// Just store parameters user entered
m_portName = portName;
m_baudRate = baudRate;
m_parity = parity;
m_dataBits = dataBits;
m_stopBits = stopBits;
m_xonxoff = xonxoff;
m_dtr = dtr;
m_rts = rts;
// Set XonXoff if set
if (xonxoff)
m_port.Handshake = Handshake.XOnXOff;
// Set DTR/RTS
m_port.DtrEnable = dtr;
m_port.RtsEnable = rts;
m_port.ReadTimeout = 500; // or some other values
m_port.WriteTimeout = 500;
// Open the port for communications
m_port.Open();
}
I will need to implement some other read write operations (according to protocol) till I can test if my mapping is right, so this is why I want to double check if I took correct approach in mapping above code to C#? Or should I take this route with PInvoke calls? Or still try my current approach? Thanks
PS. Thing is you can see this way I can't replicate all parameters that C++ calls allow one to make
I would add to initialization:
m_port.DataReceived += _serial_DataReceived;
the event to obtain data from the port. It is need for async working.
And
void _serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int _len = _serial.BytesToRead;
byte[] _out = new byte[_len];
_serial.Read(_out, 0, _len);
}
这篇关于重写串口通信从C ++到C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!