В MQL5 всегда есть место подвигу ! ;) - страница 8

 
что то каламутите воду в ступе.
Указатели на переменные, на функции, взятие адреса по ссылке - все это рестрикшоны MQL.
Это даже не то, что не предусмотрено синтаксисом, это запрет по работе с памятью.
Даже поинтер void* - это не поинтер в привычном Си-щном понимании.
Это объект для работы с объектами классов для предотвращения их копирования. 
Тоже самое референс & - это не взятие адреса, а спецификатор компилятору передавать объект без копирования оного в стэк.
Хочешь писать на Сях, пиши на Сях и импортируй dll, это пожалуйста.

Если уж очень чешутся яйца и форегн dll нельзя, то импорт с нативных dll не есть большим грехом, и ценности ваш MQL продукт от этого не потеряет.

Чтобы не пустословить, например, для работы с памятью внутри процесса терминала можно использовать просто 4-байтовый указатель и импорт memcpy

#import "msvcrt.dll"
   int memcpy(short&,short&,int);
   int memcpy(int&,int&,int);
   int memcpy(double&,double&,int);
   int memcpy(string& s,string& s,int);
#import

какой-то класс типо обертка:

struct TPtr
{
   int addr;
   TPtr():addr(0){}
   TPtr(const TPtr& r):addr(r.addr){}
   
   template<typename _T> TPtr operator =(_T& r) {
      addr = memcpy(r,r,0);
      return this;
   }
};


ну и пример юсаджа:

   string sval = "123";
   short bval = 123;
   int ival = 123;
   double dval = 123.123;

   TPtr p = sval;
   int ptrs = p.addr;
   p = bval;
   int ptrb = p.addr;
   p = ival;
   int ptri = p.addr;
   p = dval;
   int ptrd = p.addr;

Таким макаром можно орудовать памятью как угодно... Не привычные С-указатели, но тем не менее

Чем может быть полезно?
Ну например можно замутить фичу с импортом GlobalAlloc, чтобы не использовать глобальные переменные для передачи данных между модулями.
GlobalAlloc выделяет память процессу, которая не связана с хипом или статикой внутренней виртуалки под работу совы или индюка.
В нем можно размещать массивы каких угодно размеров и для индексации использовать memcpy. 

Пример импорта:

#define HANDLE int
#define LPVOID int

#import "kernel32.dll"
   HANDLE GlobalAlloc(uint flags, uint cnt);
   LPVOID GlobalLock(HANDLE hmem);
   int GlobalUnlock(HANDLE hmem);
   HANDLE GlobalFree(HANDLE hmem);
#import  "ntdll.dll"
   // GetLastError already exists in MT, so use from  WinAPI: 
   int RtlGetLastWin32Error();
#import


Пример юсаджа:

// сова N1, готовим свой массив рейтов

MqlRates rates[123];
// тут заполняем
HANDLE memid = GlobalAlloc(GMEM_MOVEABLE, 123*sizeof(MqlRates));
LPVOID ptr=GlobalLock(memid);
memcpy(ptr,rates[0].time, 123*sizeof(MqlRates));        // тут чтобы скомпилилось надо в импорте запрототипить int memcpy(int&,const datetime&,int)
GlobalUnlock(memid);
// шлем дескриптор памяти
EventChartCustom(CID, MY_SEND_DATA, memid, 0, "");

// сова N2
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   if( id == CHARTEVENT_CUSTOM+MY_SEND_DATA )
   {
      LPVOID ptr = GlobalLock((HANDLE)lparam);
      MqlRates rates[123];
      // получили рейты
      memcpy(rates[0].time,ptr,123*sizeof(MqlRates));        // тут прототип int memcpy(datetime&,const int&,int)
      GlobalUnlock(memid);
      GlobalFree(memid);
   }
}

Все.. никаких пайпов, внешних файлов, импорта левых dll
Я на скорую накидал только маленький сэмпл с большими возможностями, но полету мысли нет границ
Да, по поводу GlobalAlloc все же советую использовать GMEM_MOVEABLE, с локом и анлоком памяти, чтобы получать указатель для конкретной операции, отдавать ее назад.
Если использовать фиксированную глоб. память, то при N-ом кол-ве открытых дескрипторов может произойти фрагментация...
это как ядро ОС захочет в зависимости от нагрузки.
Удачи, хакеры )))
 
alexsis78:

Чтобы не пустословить, например, для работы с памятью внутри процесса терминала можно использовать просто 4-байтовый указатель и импорт memcpy
вы немного ошиблись веткой.
 

Есть такая книжка старая Генри Уоррен, "Алгоритмические трюки для программистов", так таких выкрутасов полно. Правда, большинство примеров не будет работать на MQL из-за отсутствия С++ указателей.

Попробую что-то веселое найти. 

 
Подобие моего примера в C вы не найдете ))) В первых это MQL, во вторых обход синтаксиса C указателей. 

Еще небольшое разъяснение для тех, кто знает плюса.

На Си:
int var = 0;         // объявим переменную var
int* ptr = &var;   // получим указатель на переменную var
int var2 = *ptr;   // скопируем значение по указателю на var в var2

В MQL:
#import "msvcrt.dll"
   uint memcpy(int& destination, const int& source, int cnt); // прототип memcpy для получения адреса переменной destination
   uint memcpy(int& destination, uint ptr, int cnt); // прототип memcpy для копирования с адреса ptr
   // компилятор подставит один из двух прототипов по разности типов второго аргумента
   // примем тип указателя например uint 
#import 

int var = 0;
uint ptr = memcpy(var,var,0); // получим указатель ptr на переменную var (здесь memcpy ничего не копирует однако возвращает адрес var)
int var2;
memcpy(var2, ptr, 4); // скопируем 4 байта или sizeof(int) с указателя ptr в переменную var2 (работает второй прототип memcpy)

Надеюсь, приемчик окажется вам полезен )))
 
alexsis78:
Подобие моего примера в C вы не найдете ))) В первых это MQL, во вторых обход синтаксиса C указателей. 
Надеюсь, приемчик окажется вам полезен )))

народ, не пишите абы что то написать.

Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.

 
o_O:

народ, не пишите абы что то написать.

Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.

Согласен, причем был описан вариант без арифметики указателей, то есть ущербный. Да и не очень они нужны, в C# их же нет. Есть unsafe, но это только для личного пользования, будет куча ограничений типа запрет на иснсталляцию по сети и т.д.
 

Хотел в кодбазу засунуть, да потом передумал:

Использование MQL5 на каггле, задача Digit Recognizer

Digit Recognizer | Kaggle
  • www.kaggle.com
Kaggle is your home for data science. Learn new skills, build your career, collaborate with other data scientists, and compete in world-class machine learning challenges.
Файлы:
sampleMNIST.mq5  25 kb
 
o_O:

народ, не пишите абы что то написать.

Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.

Почему это "не подходят" ?

Я вот уже подзабыл, где это было, и найти не мог...

Кстати,  я бы вот подвигом посчитал, сохранение указателя на массив без привлечения внешних ДЛЛ. Не хочется каждый раз при запуске индикаторов подтверждать, что я согласен импортировать функции из ДЛЛ

 
George Merts:

Почему это "не подходят" ?

Я вот уже подзабыл, где это было, и найти не мог...

Кстати,  я бы вот подвигом посчитал, сохранение указателя на массив без привлечения внешних ДЛЛ. Не хочется каждый раз при запуске индикаторов подтверждать, что я согласен импортировать функции из ДЛЛ

Заверните массив в класс, на него можно делать псевдоуказатели MQL через new
 
Alexey Volchanskiy:
Заверните массив в класс, на него можно делать псевдоуказатели MQL через new

Алексей, еще бы ты рассказал, как завернуть в класс массивы, выдаваемые функцией OnCalculate() - именно в этом случае без копирования указателей никак не обойтись.

Сейчас  - я просто копирую данные в свой класс-массива, и далее - уже тяну указатель на этот объект. Но, получается лишнее копирование, что, как я погляжу, при частых тиках и большом количестве графиков - весьма заметно добавляет "тяжести". Хочется уйти от этого копирования. Но, кроме костыля через ДЛЛ (хоть стандартную, хоть самописную) - пока ничего не предложишь.

В Сервисдеске - отбиваются, говорят, мол, "объект может быть удален". Это ихние-то собственные массивы ! Когда говоришь, что я могу объект создать, а потом удалить его и указатель будет невалиден - отвечают, что, мол, "это уже я буду за это ответственен". Налицо "двойная мораль".

И хрен бы с ней, с этой ДЛЛ - но при запуске такие индикаторы требуют постоянного подтверждения - что весьма мешает...

Причина обращения: