Упаковка структур в памяти и взаимодействие с DLL

Для хранения одного экземпляра структуры в памяти выделяется непрерывная область, достаточная, чтобы уместились все элементы.

В отличие от C++ элементы структуры идут в памяти один за другим и не выравниваются по границе 2, 4, 8 или 16 байт, в зависимости от размера самих элементов (алгоритмы выравнивания отличаются у разных компиляторов и режимов работы). Выравнивание элементов, размер которых меньше указанного блока, производится путем добавления фиктивных неиспользуемых переменных в состав структуры (программа не имеет к ним прямого доступа). Выравнивание используется для оптимизации скорости работы с памятью.

MQL5 позволяет изменять правила выравнивания при необходимости, в основном при интеграции MQL-программ со сторонними DLL-библиотеками, в которых описаны конкретные типы структур. Для них необходимо подготовить эквивалентное описание в MQL5 (см. раздел об импорте библиотек). Важно отметить, что структуры, предназначенные для интеграции, должны иметь в своем определении лишь поля ограниченного набора типов. Так, в них нельзя использовать строки, динамические массивы, а также объекты классов и указатели на объекты классов.

Управление выравниванием выполняется с помощью ключевого слова pack, добавляемого в заголовок структуры. Существует два варианта:

struct pack(размер) идентификатор
struct идентификатор pack(размер)

В обоих случаях размер — это целое число 1, 2, 4, 8, 16. Или в качестве размера можно использовать оператор sizeof(встроенный_тип), например sizeof(double).

Вариант pack(1), то есть выравнивание по границе байта, идентичен поведению по умолчанию без модификатора pack.

Узнать смещение в байтах конкретного элемента структуры от её начала позволяет специальный оператор offsetof(). Он имеет 2 параметра: объект структуры и идентификатор элемента. Например,

Print(offsetof(Resultstatus)); // 36

Перед полем status в структуре Result находятся 4 величины типа double и одна — int: итого 36.

При проектировании собственных структур рекомендуется в начале располагать самые крупные элементы, и далее остальные — в порядке уменьшения их размера.