Estructuras

Al integrar programas MQL con sistemas externos, en concreto, al enviar o recibir datos a través de Internet, se hace necesario convertir las estructuras de datos en arrays de bytes. Para ello, la API de MQL5 ofrece dos funciones: StructToCharArray y CharArrayToStruct.

En ambos casos, se supone que una estructura contiene sólo tipos integrados sencillos, es decir, todos los tipos integrados excepto líneas y arrays dinámicos. Una estructura también puede contener otras estructuras simples. Los objetos de clase y los punteros no están permitidos. Estas estructuras también se denominan POD (Plain Old Data).

bool StructToCharArray(const void &object, uchar &array[], uint pos = 0)

La función StructToCharArray copia la estructura POD object en el array array de tipo uchar. Opcionalmente, utilizando el parámetro pos puede especificar la posición en el array, a partir de la cual se colocarán los bytes. Por defecto, la copia va al principio del array, y el array dinámico aumentará automáticamente de tamaño si su tamaño actual no es suficiente para toda la estructura.

La función devuelve un indicador de éxito (true) o errores (false).

Comprobemos su rendimiento con el script ConversionStruct.mq5. Vamos a crear una nueva estructura de tipo DateTimeMsc, que incluye la estructura estándar MqlDateTime (campo mdt) y un campo adicional msc de tipo int para almacenar milisegundos.

struct DateTimeMsc
{
   MqlDateTime mdt;
   int msc;
   DateTimeMsc(MqlDateTime &initint m = 0) : msc(m)
   {
      mdt = init;
   }
};

Dentro de la función OnStart , vamos a convertir un valor de prueba datetime a nuestra estructura, y luego al array de bytes.

MqlDateTime TimeToStructInplace(datetime dt)
{
   static MqlDateTime m;
   if(!TimeToStruct(dtm))
   {
      // the error code, _LastError, can be displayed
      // but here we just return zero time
      static MqlDateTime z = {};
      return z;
   }
   return m;
}
 
#define MDT(TTimeToStructInplace(T)
 
void OnStart()
{
   DateTimeMsc test(MDT(D'2021.01.01 10:10:15'), 123);
   uchar a[];
   Print(StructToCharArray(testa));
   Print(ArraySize(a));
   ArrayPrint(a);
}

Obtendremos el siguiente resultado en el registro (el array está reformateado con saltos de línea adicionales para enfatizar la correspondencia de bytes a cada uno de los campos):

   true
   36
   229   7   0   0
     1   0   0   0
     1   0   0   0
    10   0   0   0
    10   0   0   0
    15   0   0   0
     5   0   0   0
     0   0   0   0
   123   0   0   0

 

bool CharArrayToStruct(void &object, const uchar &array[], uint pos = 0)

La función CharArrayToStruct copia el array array del tipo uchar en la estructura POD object. Utilizando el parámetro pos, puede especificar la posición en el array desde la que empezar a leer bytes.

La función devuelve un indicador de éxito (true) o errores (false).

Continuando con el mismo ejemplo (ConversionStruct.mq5), podemos restaurar la fecha y hora originales desde el array de bytes.

void OnStart()
{
   ...
   DateTimeMsc receiver;
   Print(CharArrayToStruct(receivera));                 // true
   Print(StructToTime(receiver.mdt), "'"receiver.msc);  // 2021.01.01 10:10:15'123
}