R – How to send null characters to the serial port using the Windows API


I am working on a Windows utility program which communicates with some custom hardware using a standard COM port. The communication protocol (which is out of my control) requires me to transmit and receive raw 8-bit data bytes.

I am currently using the following Windows API function to send data to the COM port:

WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)

where hFile is a reference to the properly opened COM port, and lpBuffer is an array of bytes that I have stored in memory. The code works perfectly until a null character (ASCII zero) needs to be sent to the device. WriteFile stops sending as soon as it detects the null character because it assumes that it has reached the end of the string. This happens even though I set numberOfBytesToWrite properly.

How can I send raw data to the COM port using the Windows API? I would prefer to use a standard API call similar to WriteFile, but I am open to suggestions.

I am currently using RapidQ to build the utility, but all it does is call the Windows API function directly.

Edit: My setup consists of a Windows PC connected via serial port to the custom hardware module. The module has a small screen on which I am able to view the transmitted characters. I have tested this setup with another third-party utility program. I am able to communicate with the module using this third party program, and null characters show up properly. In my own program, when I use WriteFile, a null character anywhere in the transmit stream stops the rests of the stream from being sent.

Best Solution

I've done Windows serial port programming before, and am sure that I have been able to send null characters through the serial ports (various file transfer protocols wouldn't have worked otherwise). I can think of two possible explanations:

  1. The receiving device is printing the data it received using a method that stops at the first null character. How are you determining that the transmitting device is terminating at the first null? Could the problem be somewhere further down the line?
  2. The serial driver is broken. This is rather unlikely, but is a possible explanation. If you are using some dodgy proprietary third party serial port and its drivers, then they might be suspect. If you are using a standard built-in serial port with the normal Windows drivers, then this is probably not a problem.

I just had a quick look at RapidQ and there's a third possible explanation:

  1. The marshaling that RapidQ may do in the process of calling Win32 API functions may have trouble with embedded null characters in the data to send. I don't know anything about RapidQ, but this is yet another link in the chain that must be considered.
Related Question