Вчера обсуждали, страница 1687. :) Но читать лучше вот с этого сообщения на 1686-й странице: https://www.mql5.com/ru/forum/1111/page1686#comment_2790746 Кстати, человек на Ваш же вопрос отвечал. Просто получается, что схема такая. Запрос на вызов индикатора попадает в Терминал. Т.е. советник или скрипт не вызывают индикатор напрямую, терминал выступает посредником. В терминале происходит проверка, существует ли уже такой индикатор с указанными параметрами. Если да, то он возвращает программе, вызвавшей индикатор, хэндл (ссылку) на уже существующий индикатор. А в своих терминальных недрах помечает в счётчике, что был ещё один вызов на данный индикатор. Т.е. он ведёт учёт, сколько хэндлов на данный индикатор вернул. Когда кто-то делает IndicatorRelease, это не значит, что остальным, кто вызвал этот же индикатор с такими же параметрами, этот индикатор больше не нужен. Поэтому Терминал уменьшает счётчик на единицу, но оставляет индикатор активным, потому-что им ещё кто-то пользуется. Так будет продолжаться до тех пор, пока счётчик не обнулится. А вот когда он обнулится, тогда Терминал окончательно и бесповоротно удалит данный индикатор из оперативной памяти. Если Вы попробуете создать код, который будет содержать IndicatorRelease, но при этом не будет содержать вызова самого индикатора, то я думаю, что Вы его просто-напросто не откомпилируете, потому-что в IndicatorRelease нужно передавать хэндл, а если индикатор не вызывался из программы, то и хэндл вы не узнаете.
BlackTomcat: Вчера обсуждали, страница 1687. :) Но читать лучше вот с этого сообщения на 1686-й странице: https://www.mql5.com/ru/forum/1111/page1686#comment_2790746 Кстати, человек на Ваш же вопрос отвечал. Просто получается, что схема такая. Запрос на вызов индикатора попадает в Терминал. Т.е. советник или скрипт не вызывают индикатор напрямую, терминал выступает посредником. В терминале происходит проверка, существует ли уже такой индикатор с указанными параметрами. Если да, то он возвращает программе, вызвавшей индикатор, хэндл (ссылку) на уже существующий индикатор. А в своих терминальных недрах помечает в счётчике, что был ещё один вызов на данный индикатор. Т.е. он ведёт учёт, сколько хэндлов на данный индикатор вернул. Когда кто-то делает IndicatorRelease, это не значит, что остальным, кто вызвал этот же индикатор с такими же параметрами, этот индикатор больше не нужен. Поэтому Терминал уменьшает счётчик на единицу, но оставляет индикатор активным, потому-что им ещё кто-то пользуется.
Спасибо! Получается отличная экономия.
Если Вы попробуете создать код, который будет содержать IndicatorRelease, но при этом не будет содержать вызова самого индикатора, то я думаю, что Вы его просто-напросто не откомпилируете, потому-что в IndicatorRelease нужно передавать хэндл, а если индикатор не вызывался из программы, то и хэндл вы не узнаете.
Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
А вы не передавайте. :) Или хотя бы не вызывайте IndicatorRelease() для полученного таким образом хэндла. Если же вы так сделаете, то это будет уже ваша ошибка, а не баг языка, согласны?
Sergei Vladimirov: А вы не передавайте. :) Или хотя бы не вызывайте IndicatorRelease() для полученного таким образом хэндла. Если же вы так сделаете, то это будет уже ваша ошибка, а не баг языка, согласны?
А я нехорошую закладку для бесплатного Маркета напишу, которая в определенный момент будет просто перебирать весь положительный диапазон int и для каждого пробовать IndicatorRelease.
Такой скрипт накроет все советники и индикаторы терминала, что использовали iCustom без ChartIndicatorAdd.
Это, опять же, будут ваши преднамеренные действия, а не баг языка. К чему вы это написали-то?
Кстати, этот разговор начался с вашего вопроса, как проверить хэндл индикатора перед его использованием. Так вот, хэндл проверить нельзя, но при попытке использования хэндла закрытого индикатора получите ошибку 4807 - вот, её и отcлеживайте после каждого вызова CopyBuffer(), если она вернёт -1.
fxsaber: Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
Эмм... Глобальные переменные чего? Терминала или советника? С переменными Терминала никогда не работал, поэтому рассуждать на эту тему не буду. А что касается глобальных переменных советника, то тут это основной способ. Если индикаторы инициализируются в OnInit, а IndicatorRelease происходит в OnDeinit, то тут только глобальными переменными (советника) и получится передать хэндлы.
Функция позволяет удалять хэндл индикатора, если он больше не нужен, и таким образом позволяет экономить память. Удаление хендла производится сразу, удаление расчетной части индикатора производится через некоторое небольшое время (если обращений к ней больше нет).
В обычной жизни хэндлы индикаторов удаляются автоматически при выгрузке программы. Эта функция нужна для управления памятью в сложных комбайнах. Либо, как Вы сами выше сказали, тогда когда точно известно, что данные этого индикатора больше не понадобятся
Что за счетчик?
Если Вы попробуете создать код, который будет содержать IndicatorRelease, но при этом не будет содержать вызова самого индикатора, то я думаю, что Вы его просто-напросто не откомпилируете, потому-что в IndicatorRelease нужно передавать хэндл, а если индикатор не вызывался из программы, то и хэндл вы не узнаете.
BlackTomcat:
Вчера обсуждали, страница 1687. :) Но читать лучше вот с этого сообщения на 1686-й странице: https://www.mql5.com/ru/forum/1111/page1686#comment_2790746 Кстати, человек на Ваш же вопрос отвечал. Просто получается, что схема такая. Запрос на вызов индикатора попадает в Терминал. Т.е. советник или скрипт не вызывают индикатор напрямую, терминал выступает посредником. В терминале происходит проверка, существует ли уже такой индикатор с указанными параметрами. Если да, то он возвращает программе, вызвавшей индикатор, хэндл (ссылку) на уже существующий индикатор. А в своих терминальных недрах помечает в счётчике, что был ещё один вызов на данный индикатор. Т.е. он ведёт учёт, сколько хэндлов на данный индикатор вернул. Когда кто-то делает IndicatorRelease, это не значит, что остальным, кто вызвал этот же индикатор с такими же параметрами, этот индикатор больше не нужен. Поэтому Терминал уменьшает счётчик на единицу, но оставляет индикатор активным, потому-что им ещё кто-то пользуется.
Спасибо! Получается отличная экономия.
Если Вы попробуете создать код, который будет содержать IndicatorRelease, но при этом не будет содержать вызова самого индикатора, то я думаю, что Вы его просто-напросто не откомпилируете, потому-что в IndicatorRelease нужно передавать хэндл, а если индикатор не вызывался из программы, то и хэндл вы не узнаете.
Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.А вы не передавайте. :) Или хотя бы не вызывайте IndicatorRelease() для полученного таким образом хэндла. Если же вы так сделаете, то это будет уже ваша ошибка, а не баг языка, согласны?
А я нехорошую закладку для бесплатного Маркета напишу, которая в определенный момент будет просто перебирать весь положительный диапазон int и для каждого пробовать IndicatorRelease.
Такой скрипт накроет все советники и индикаторы терминала, что использовали iCustom без ChartIndicatorAdd.
Это, опять же, будут ваши преднамеренные действия, а не баг языка. К чему вы это написали-то?
Кстати, этот разговор начался с вашего вопроса, как проверить хэндл индикатора перед его использованием. Так вот, хэндл проверить нельзя, но при попытке использования хэндла закрытого индикатора получите ошибку 4807 - вот, её и отcлеживайте после каждого вызова CopyBuffer(), если она вернёт -1.
Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
Ошибка при выполнении: 'invalid pointer access' (*)
А на что у вас здесь "A::а" указывает?
После - не значит сразу. Но если не надо, то когда надо?
Читайте документацию
Примечание
Функция позволяет удалять хэндл индикатора, если он больше не нужен, и таким образом позволяет экономить память. Удаление хендла производится сразу, удаление расчетной части индикатора производится через некоторое небольшое время (если обращений к ней больше нет).
Слишком большой кусок вырезал - позже доделаю
Если сделать указатель валидным, то ваш пример работает: