- Home /
Trouble creating a C# UDP interface to a C++ app in Unity
Okay... I do C/C++ in my sleep... C#, not so much. Still wrapping my head around that.
I have a fairly basic problem: I have a very large and complex application written in C++ that I need to exchange data with via UDP. The UDP part is easy. Where I'm getting my pants in a wad is mapping the C++ message structures into C# structures. I cannot modify the C++ structures as I have to emulate a piece of physical hardware within the Unity3D space (transparently to the C++ app)
So... for example, here's a simple C++ structure that matches the ICD for one of the pieces of hardware...
struct RequestMessageType
{
//MESSAGE TYPE 2
unsigned char msg_type;
char port_a_output[8];
char port_b_output[8];
char port_d_output[8];
unsigned short serialLength;
char serialData[256];
unsigned short checksum;
};
As I understand it, I could represent this in a C# structure as follows...
protected unsafe struct RequestMessageType
{
public byte messageType;
public fixed byte portAOutput[8];
public fixed byte portBOutput[8];
public fixed byte portCEOutput[8];
public ushort serialLength;
public fixed byte serialData[256];
public ushort checksum;
};
The catch being that I cannot use 'unsafe' with Unity.
So... any chance one of the Unity/C# gurus can lend an old C++ programmer a hand in understanding how to create a C# structure to receive the message and how to map the raw byte[] returned from the UdpClient.Receive() call into that structure?
Or... is it as I fear, and I'm going to have to use brute force to manually stuff the data from the byte array into a C# structure?
TIA for any assists on this.
EDIT: I am can good speak engleesh
Answer by Bunny83 · Aug 17, 2012 at 05:41 PM
Yes, you probably have to "deserialize" it manually. You can use a BinaryReader for example.
using System.IO;
// [...]
byte[] data;
RequestMessageType request;
// [...]
BinaryReader reader = new BinaryReader(new MemoryStream(data));
request.messageType = reader.ReadByte();
for (int i = 0; i < 8; i++)
request.port_a_output[i] = reader.ReadByte();
for (int i = 0; i < 8; i++)
request.portBOutput[i] = reader.ReadByte();
for (int i = 0; i < 8; i++)
request.portCEOutput[i] = reader.ReadByte();
request.serialLength = reader.ReadUInt16();
for (int i = 0; i < 256; i++)
request.serialData[i] = reader.ReadByte();
request.checksum = reader.ReadUInt16();
I would write a constructor for the RequestMessageType struct that takes a byte array ;)
Note that $$anonymous$$emoryStream assumes that all the bytes in the array are unsigned. This answer did not work with doubles for me, however, BitConverter did.
Answer by kspiel · Aug 17, 2012 at 08:26 PM
Thank you Bunny83 --
You confirmed what I thought and this did get the trick done. Appreciate you lending a hand to a C# noob.