Je fais passer des paquets de données de 64 octets par USB à un microcontrôleur. Dans le code C du microcontrôleur, les paquets ont la structure suivante,
typedef union
{
unsigned char data[CMD_SIZE];
cmd_get_t get;
// plus more union options
} cmd_t;
avec
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;
y
typedef struct
{
int16_t supply;
int16_t current[4];
} cmd_get_adc_t;
Du côté du PC, en C#, on m'a fourni une fonction qui renvoie le paquet de 64 octets sous la forme d'un Byte[]. La fonction utilise Marshal.Copy pour copier les données reçues dans le tableau Byte[]. J'ai ensuite utilisé une structure C# de la forme
[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;
}
et j'ai de nouveau utilisé Marshal.Copy pour copier le tableau d'octets dans le struct afin de pouvoir travailler avec des données structurées, par exemple
COMMAND_GET_ADC cmd = (COMMAND_GET_ADC)RawDeserialize(INBuffer, 1, typeof(COMMAND_GET_ADC));
short supply = cmd.Supply;
avec
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;
}
J'ai l'impression que je fais beaucoup de copies des données et que ce n'est peut-être pas le moyen le plus productif d'obtenir ce que je veux. Je dois également reconvertir les données structurées en un tableau d'octets pour les commandes au dispositif. J'ai une méthode qui utilise le même processus (c'est-à-dire utiliser une structure, puis la sérialiser en un tableau d'octets et passer le tableau d'octets à la fonction d'écriture).
Existe-t-il de meilleures alternatives ?