2

Is it possible that .Net SerialPort and VB6 MSComm work different?

In both cases, I´m reading data from the buffer, and both got me different strings, if I import the MSComm dll into my .Net project, It works perfectly (obviously).

Does anyone have more in deep information?

If it helps, here are my to simple samples, in both cases I send the same Byte Array...

VB6:

Dim MSComm1 As Object
Dim ArrToSend() As Byte
Dim IncomeData As String
Set MSComm1 = CreateObject("MSCommLib.MSComm")
With MSComm1
    .CommPort = 1
    .PortOpen = True
End With

ReDim ArrToSend(4)
ArrToSend(0) = 179
ArrToSend(1) = 1
ArrToSend(2) = 92
ArrToSend(3) = 92
MSComm1.Output = ArrToSend
IncomeData = MSComm1.Input

c#

SerialPort _serialPort = new SerialPort();
_serialPort.Open();
Byte[] _bytesToSend = new Byte[4];
_bytesToSend[0] = 179;
_bytesToSend[1] = 1;
_bytesToSend[2] = 92;
_bytesToSend[3] = 92;
_serialPort.Write(_bytesToSend, 0, _bytesToSend.Length);
String ReadExisting = _serialPort.ReadExisting();
Charles
  • 50,943
  • 13
  • 104
  • 142
Rama
  • 429
  • 1
  • 8
  • 14
  • 3
    What's the difference between the two strings? Are you checking for receive errors (e.g. parity errors)? Why aren't you setting/specifying the COM port parameters: for example baud rate, stop bits, and parity? – ChrisW Jan 27 '11 at 17:36
  • I've written a lot of serial port code, both native and .NET, and IMO System::IO::Ports::SerialPort and MSCOMM.OCX are both trash. They take the robust and powerful Win32 serial port API and abuse it forcing you into bad practices. If you want to write robust code, you'll have to use p/invoke (or what I did, a C++/CLI wrapper). – Ben Voigt Jan 27 '11 at 18:30
  • @Ben Voigt What is a C++/CLI wrapper if not pinvoke? I thought that C++/CLI was only for porting legacy (unmanaged) C++ to .NET; does it also help somehow with accessing unmanaged APIs from managed code? – ChrisW Jan 27 '11 at 18:45
  • @ChrisW: Very much YES. In C#, you need hundreds of lines of p/invoke function declarations, DllImport attributes, and struct definitions which have to match the memory layout exactly. With C++/CLI, `#include ` and the compiler does all the rest. – Ben Voigt Jan 27 '11 at 19:26
  • @Ben Voigt - Thanks for your answer. Is it 'just' syntactic sugar, i.e. exactly the same managed-to-unmanaged overhead as pinvoke at run-time? – ChrisW Jan 27 '11 at 19:34
  • @ChrisW: If you specify `/clr:pure` then the C++/CLI compiler will use p/invoke, although you still benefit from the correct signatures being generated for you. With `/clr` though, it will use more efficient C++ interop (often called "It Just Works" by the Visual C++ team). Plus you can control where the native/managed transition happens by writing native helper functions as well as managed. – Ben Voigt Jan 27 '11 at 19:48
  • @ChrisW: The differences is that they have different characters. I'm not checking for any error as I'm not getting any... and I'm taking the default parameters... – Rama Jan 30 '11 at 05:48

2 Answers2

5

You are mixing bytes and strings. MSComm was very lax about it but SerialPort cares about text encoding. Clearly you are using a binary protocol, it is likely that your received string is containing question marks for bytes that could not be converted to the SerialPort.Encoding (default is ASCII). You have to use the Read() method to get the response.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I Do recieve question marks for bytes in my string (squares actually), by I separate them into Chars, and there I have the ASCII code, doing that would't be the same as using Read() within a for loop? Either way, I'm gonna test your answer on monday (I turn of the devices at the office so I would't work from home...) – Rama Jan 30 '11 at 05:47
1

I expect that they both use the underlying O/S API; but I guess that they may each use that API in difference ways: e.g. with different default COM port parameters (if you don't specify the parameters explicitly).

Another difference may be in the timing: when you read the input/reply, how do you know whether it's been sent yet, and how do you know whether the 'read' or 'input' function is waiting for long enough?

ChrisW
  • 54,973
  • 13
  • 116
  • 224
  • I'm doing a Thread.Sleep before the reading, to make sure I have a response, which I have, but with different characters... – Rama Jan 30 '11 at 05:53