
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Указатели на переменные, на функции, взятие адреса по ссылке - все это рестрикшоны MQL.
Это даже не то, что не предусмотрено синтаксисом, это запрет по работе с памятью.
Даже поинтер void* - это не поинтер в привычном Си-щном понимании.
Это объект для работы с объектами классов для предотвращения их копирования.
Тоже самое референс & - это не взятие адреса, а спецификатор компилятору передавать объект без копирования оного в стэк.
Хочешь писать на Сях, пиши на Сях и импортируй dll, это пожалуйста.
Если уж очень чешутся яйца и форегн dll нельзя, то импорт с нативных dll не есть большим грехом, и ценности ваш MQL продукт от этого не потеряет.
Чтобы не пустословить, например, для работы с памятью внутри процесса терминала можно использовать просто 4-байтовый указатель и импорт memcpy
какой-то класс типо обертка:
Таким макаром можно орудовать памятью как угодно... Не привычные С-указатели, но тем не менее
Чем может быть полезно?
Ну например можно замутить фичу с импортом GlobalAlloc, чтобы не использовать глобальные переменные для передачи данных между модулями.
GlobalAlloc выделяет память процессу, которая не связана с хипом или статикой внутренней виртуалки под работу совы или индюка.
В нем можно размещать массивы каких угодно размеров и для индексации использовать memcpy.
Пример импорта:
#define HANDLE int
#define LPVOID int
Пример юсаджа:
// сова 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-ом кол-ве открытых дескрипторов может произойти фрагментация...
это как ядро ОС захочет в зависимости от нагрузки.
Удачи, хакеры )))
Чтобы не пустословить, например, для работы с памятью внутри процесса терминала можно использовать просто 4-байтовый указатель и импорт memcpy
Есть такая книжка старая Генри Уоррен, "Алгоритмические трюки для программистов", так таких выкрутасов полно. Правда, большинство примеров не будет работать на MQL из-за отсутствия С++ указателей.
Попробую что-то веселое найти.
Еще небольшое разъяснение для тех, кто знает плюса.
На Си:
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)
Надеюсь, приемчик окажется вам полезен )))
Подобие моего примера в C вы не найдете ))) В первых это MQL, во вторых обход синтаксиса C указателей.
Надеюсь, приемчик окажется вам полезен )))
народ, не пишите абы что то написать.
Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.
народ, не пишите абы что то написать.
Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.
Хотел в кодбазу засунуть, да потом передумал:
Использование MQL5 на каггле, задача Digit Recognizer
народ, не пишите абы что то написать.
Все эти варианты с memcpy пережеваны несколько лет назад и для данной темы не подходят.
Почему это "не подходят" ?
Я вот уже подзабыл, где это было, и найти не мог...
Кстати, я бы вот подвигом посчитал, сохранение указателя на массив без привлечения внешних ДЛЛ. Не хочется каждый раз при запуске индикаторов подтверждать, что я согласен импортировать функции из ДЛЛ
Почему это "не подходят" ?
Я вот уже подзабыл, где это было, и найти не мог...
Кстати, я бы вот подвигом посчитал, сохранение указателя на массив без привлечения внешних ДЛЛ. Не хочется каждый раз при запуске индикаторов подтверждать, что я согласен импортировать функции из ДЛЛ
Заверните массив в класс, на него можно делать псевдоуказатели MQL через new
Алексей, еще бы ты рассказал, как завернуть в класс массивы, выдаваемые функцией OnCalculate() - именно в этом случае без копирования указателей никак не обойтись.
Сейчас - я просто копирую данные в свой класс-массива, и далее - уже тяну указатель на этот объект. Но, получается лишнее копирование, что, как я погляжу, при частых тиках и большом количестве графиков - весьма заметно добавляет "тяжести". Хочется уйти от этого копирования. Но, кроме костыля через ДЛЛ (хоть стандартную, хоть самописную) - пока ничего не предложишь.
В Сервисдеске - отбиваются, говорят, мол, "объект может быть удален". Это ихние-то собственные массивы ! Когда говоришь, что я могу объект создать, а потом удалить его и указатель будет невалиден - отвечают, что, мол, "это уже я буду за это ответственен". Налицо "двойная мораль".
И хрен бы с ней, с этой ДЛЛ - но при запуске такие индикаторы требуют постоянного подтверждения - что весьма мешает...