Обсуждение статьи "Избавляемся от балласта самодельных DLL" - страница 2

 

Автору статьи большая благодарность за столь доступное представление информации о возможностях взаимодействия IPC без велосипедных dll.

Работа с памятью мне кажется достаточно сложной, но подход понятен, за исключением некоторых вопросов, надеюсь знающие люди помогут разобраться:

1. При помощи memcpy копируем в массив uchar[2] двухбайтовую переменную short, как информация ложится в сам массив?

В каком формате будут находиться значения по индексу 0 и 1 массива uchar?

uchar dst[2];
short src = 13331;
memcpy(dst, src, sizeof(src));

uchar[0] = ?, uchar[1] = ?;

Значение разбивается побайтно и пишется в массив, ок ... Тут вроде понятно.

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


2.  Как правильно заполнить массив uchar[4] значениями разных типов при копировании memcpy, например:

uchar dst[4];
short src1 = 2;
short src2 = 13331;
memcpy(dst, src1, sizeof(src1));
memcpy(dst, src2, sizeof(src2)); // Перезаписывает уже существующее значение, т.е.,  как я предполагаю, нужно при записи в dst указывать адрес уже со смещением на 2 байта после записи src1.

Чувствуется что ответ тривиален и все делается просто, но как это правильно записать ?

 

Print не пробовали?

 

Четвёртый пример ошибку выдаёт : 'operator=' - illegal operation use SAMPLE_04.mq4 34 7

#property copyright ""

#property link      ""

#property version   ""

#property strict

//Пример 4. Копирование структур средствами MQL5

//---

struct str1

{

  double d; // 8 байт

  long   l; // 8 байт

  int i[3]; // 3 * 4 = 12 байт

};

//---

struct str2

{

  uchar c[ 8 + 8 + 12 ]; // размер структуры str1

};

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart(){

  str1 src;   // 

  src.d = -1; // 

  src.l = 20; //

  //--- заполняем параметры структуры

  ArrayInitialize(src.i, 0); 

  str2 dst;  //  

  //--- превратили структуру в байтовый массив

  dst = src; //   <----- Ошибка

}


Сама идея про участок памяти понятна, может в определениях где то не всё ровненько?

Подскажите в чём причина?

Заранее спасибо. 
 
_SERG_:

Сама идея про участок памяти понятна, может в определениях где то не всё ровненько?

Подскажите в чём причина?

структуры разных типов уже нельзя копировать, язык MQL возможность убрал

пользуйтесь union

//Пример 4. Копирование структур средствами MQL5
//---
struct str1
{
  double d; // 8 байт
  long   l; // 8 байт
  int i[3]; // 3 * 4 = 12 байт
};

//---
struct str2
{
  uchar c[ 8 + 8 + 12 ]; // размер структуры str1
};

union str12 { str1 s1; str2 s2; };

//------------------------------------------------------------------
void OnStart()
{
  str12 src;
  src.s1.d = -1; // 
  src.s1.l = 20; //
  ArrayInitialize(src.s1.i, 0); 

  // src.s2 - байтовый массив от s1
}
 
_SERG_:


uchar по ходу неправильно,  и там double присутствует тоже подозрительно.

И по ходу src надо указать что именно ей принадлежит и будет передаваться.

Вам уже кто-то подправил так же как и предположил. Хорошо. Думайте. Удачи.

 
а для mql4 будет работать на сегодняшний день?
 
Seric29:
а для mql4 будет работать на сегодняшний день?

языки (MQL4 / MQL5)  сейчас полностью одинаковы - отличие в 2-3  функциях отсутствующих в MQL4 (ArrayPrint и что то еще по мелочи) и в "новых плюшках" для MQL5 - БД, DirectX и OpenCL


но статья написана 8 лет назад, сейчас MQL стал строго типизированным языком, и чтобы присвоить 2 структуры (пример в статье) нужно писать самостоятельно конструктор копирования или сериализовать структуру в массив байт и затем обратно

 
Ваша статья очень помогла мне, но как скопировать в статье не упоминается указатель функции, потому что мне нужно поместить указатель функции обратного вызова, переданный как Я не знаю, как это реализовать.
 
Example 4. Copying the structures by means of MQL5
struct str1
{
  double d; // 8 байт
  long l;   // 8 байт
  int i[3]; // 3*4=12 байт
};
struct str2
{
  uchar c[8+8+12]; // размер структуры str1
};
//+------------------------------------------------------------------+
//| Функция запуска программы сценария|
//+------------------------------------------------------------------+
void OnStart()
{
  str1 src; 
  src.d=-1;
  src.l=20;
  //--- заполнение параметров структуры
  ArrayInitialize(src.i, 0); 
  str2 dst;
  //--- превращение структуры в байтовый массив
  dst=src; 
}

Присвоение структур разных типов больше не работает( преобразованиепараметров не разрешено - ожидается переменная того же типа).

Но можно было бы работать с союзами:

struct str1
{
  double d; // 8 байт
  long l;   // 8 байт
  int i[3]; // 3*4=12 байт
};
struct str2
{
  uchar c[8+8+12]; // размер структуры str1
};
union union1
{
  str1 src;
  str2 dst;
};

//+------------------------------------------------------------------+
//| Функция запуска программы сценария|
//+------------------------------------------------------------------+
void OnStart()
{
  union1 u; 
  u.src.d=-1;
  u.src.l=20;
  //--- заполнение параметров структуры
  ArrayInitialize(u.src.i, 0); 

  //--- байтовый массив, представляющий структуру, находится в файле dst.c
  ArrayPrint(u.dst.c);
 
Интересно, можно ли получить реальный указатель на функцию. Указатели, полученные с помощью typedef, отлично работают внутри mql программы. Но к сожалению передать в dll мне их не удалось.