If your C++ program host is IBM-PC compatible machine you must perform byte swap on your C# client. If is not than you must not.
To communicate with C# programs you must reverse data you read wich is bigger than 1 byte, because C# use big-endian byte order instead of little-endian of native C++. To swap WORD(16 bits) and DWORD(32 bits) you may use this macro
// BYTE SWAPING IN WORD and DWORD
#define WORD_SWAP(x) ((((x) >> 8) & 0x00ff) | (((x) << 8) & 0xff00))
#define DWORD_SWAP(x) ((((x) >> 24) & 0x000000ff) | \
(((x) >> 8) & 0x0000ff00) | \
(((x) << 8) & 0x00ff0000) | \
(((x) << 24) & 0xff000000))
or similar function in C#. Apply only to separate stucture fields.
PS: Do not forget compiler packing features to correct data meaning on both sides.
For more info visit Endianness, Data structure alignment
So people ask me to do the same in C#
// Swaps uint16_t
ushort Swap(ushort x)
{
return (ushort)((((x) >> 8) & 0x00ff) | (((x) << 8) & 0xff00));
}
// Swaps uint32_t
uint Swap(uint x)
{
return ((((x) >> 24) & 0x000000ff) |
(((x) >> 8) & 0x0000ff00) |
(((x) << 8) & 0x00ff0000) |
(((x) << 24) & 0xff000000));
}
work with C# structures client means UDPClient object. It is all must be performed in low level manner.
struct mdata
{
UInt32 mark_kupnr;
UInt16 mark_provnr;
UInt16 markriktning;
UInt16 xpos;
UInt16 ypos;
}
// example of mdata read with sockets
mbata data;
var bytes = client.Receive()
data.mark_kupnr = Swap(BitConverter.ToUInt32(bytes, 0));
data.mark_provnr = Swap(BitConverter.ToUInt16(bytes, 4));
data.markriktning = Swap(BitConverter.ToUInt16(bytes, 6));
data.xpos = Swap(BitConverter.ToUInt16(bytes, 8));
data.ypos = Swap(BitConverter.ToUInt16(bytes, 10));
Form output data you must do reverse from UInt32 and UInt16 to byte array. Than merge all of this in proper order using List<byte>.AddRange(variable_byte_array); than cast this formed list to array of bytes and use UDPClient.Send(formed_array);.
Array in C++ places in memory at this order [0][1][2][3][4][5][6][7][8][9].
So you must sequentualy read mdata structure 10 times form 0 to 9.
// read first data
typedef struct
{
UInt32 kupnr;
UInt16 lngd;
UInt16 bredd;
UInt16 tjocklek;
sbyte slagkraft;
byte antal;
// now read mkdata 10 times
struct mdata mark[10];
} markdata; // we have done with markdata
No one holds you to use classes instead of structures. It will be simpler to deal with arrays considering we use byte (binary) serialization at all. Than add to each class proper method (for example)
mdata class or structure methods
void Receive(UDPClient client)
{
var bytes = client.Receive()
mark_kupnr = Swap(BitConverter.ToUInt32(bytes, 0));
mark_provnr = Swap(BitConverter.ToUInt16(bytes, 4));
markriktning = Swap(BitConverter.ToUInt16(bytes, 6));
xpos = Swap(BitConverter.ToUInt16(bytes, 8));
ypos = Swap(BitConverter.ToUInt16(bytes, 10));
}
void Send(UDPClient client)
{
var listOfBytes = new List<byte>();
listOfBytes.AddRange(BitConverter.GetBytes(Swap(mark_kupnr)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(mark_provnr)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(markriktning)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(xpos)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(ypos)));
client.Send(listOfBytes.ToArray(), listOfBytes.Count);
}
void Receive(byte[] bytes)
{
mark_kupnr = Swap(BitConverter.ToUInt32(bytes, 0));
mark_provnr = Swap(BitConverter.ToUInt16(bytes, 4));
markriktning = Swap(BitConverter.ToUInt16(bytes, 6));
xpos = Swap(BitConverter.ToUInt16(bytes, 8));
ypos = Swap(BitConverter.ToUInt16(bytes, 10));
}
void Send(out byte[] bytes)
{
var listOfBytes = new List<byte>();
listOfBytes.AddRange(BitConverter.GetBytes(Swap(mark_kupnr)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(mark_provnr)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(markriktning)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(xpos)));
listOfBytes.AddRange(BitConverter.GetBytes(Swap(ypos)));
bytes = listOfBytes.ToArray();
}
array in your markdata class not suppoused to be fixed so you just create that number of elements in your class that you want. All dirty work will go to the send and receive methods.
to deal with arrays you can add byte shift value to step through mdata array.
charis C#sbyte.