I am passing 64 byte data packets over USB to a microcontroller. In the microcontroller C code the packets have the structure,
typedef union
{
unsigned char data[CMD_SIZE];
cmd_get_t get;
// plus more union options
} cmd_t;
with
typedef struct
{
unsigned char cmd; //!< Command ID
unsigned char id; //!< Packet ID
unsigned char get_id; //!< Get identifier
unsigned char rfu[3]; //!< Reserved for future use
union
{
unsigned char data[58]; //!< Generic data
cmd_get_adc_t adc; //!< ADC data
// plus more union options
} data; //!< Response data
} cmd_get_t;
and
typedef struct
{
int16_t supply;
int16_t current[4];
} cmd_get_adc_t;
On the PC side in C# I have been provided with a function which returns the 64 byte packet as a Byte[]. The function uses Marshal.Copy to copy the received data into the Byte[] array. I then used a C# struct of the form
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct COMMAND_GET_ADC
{
public byte CommandID;
public byte PacketID;
public byte GetID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
public byte[] RFU;
public short Supply;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public short[] Current;
}
and again used Marshal.Copy to copy the byte array into the struct so that I could work with is as structured data, e.g.
COMMAND_GET_ADC cmd = (COMMAND_GET_ADC)RawDeserialize(INBuffer, 1, typeof(COMMAND_GET_ADC));
short supply = cmd.Supply;
with
public static object RawDeserialize(Byte[] rawData, int position, Type anyType)
{
int rawsize = Marshal.SizeOf(anyType);
if(rawsize > rawData.Length)
{
return null;
}
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawData, position, buffer, rawsize);
object retobj = Marshal.PtrToStructure(buffer, anyType);
Marshal.FreeHGlobal(buffer);
return retobj;
}
This just feels like I am making lots of copies of the data and like it might not be the most productive way of achieving what I want to. I also need to convert the structured data back to a byte array for commands to the device. I have a method which uses the same process (i.e. use a struct and then serialise it to a byte array and pass the byte array to the write function).
Are there better alternatives?
To convert temperatures in degrees Fahrenheit to Celsius, subtract 32 and multiply by .5556 (or 5/9).
The most common way to convert alternating current into direct current is to use one or more diodes, those handy electronic components that allow current to pass in one direction but not the other. Although a rectifier converts alternating current to direct current, the resulting direct current isn't a steady voltage.
A calculator helps here. To convert Fahrenheit to Celsius, subtract 32 degrees and divide by 1.8. To convert Celsius to Fahrenheit, multiply by 1.8 and add 32 degrees.
If you can use unsafe code, you can cast the byte array to a pointer to your structure using the 'fixed' keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With