问题
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
回答1:
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);
}
来源:https://stackoverflow.com/questions/32859276/rewrite-serial-port-communicationf-rom-c-to-c-sharp