Ошибки, баги, вопросы - страница 2540

 
Roman:
По моему есть проблема с деинициализацией dll в Сервисах, помогите разобраться.

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

в любом случае то что вы делаете при DLL_PROCESS_DETACH это уже поздно. Сделайте явную функцию deinit в длл которая будет выставлять этот флаг и явно вызываться при завершении сервиса.

[Удален]  
Roman: 

Терминал начнет выгружать либу после возвращения потока из старт(), думаю. А то как получается? Программа работает, и начать ей окружение ломать? Ерунда ведь. Запустите в либе отдельный поток, а  не гоняя в цикле поток скрипта, и вот его уже сможет нормально завершить.

 
Vict:

Терминал начнет выгружать либу после возвращения потока из старт(), думаю. А то как получается? Программа работает, и начать ей окружение ломать? Ерунда ведь. Запустите в либе отдельный поток, и вот его уже сможет нормально завершить.

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

Попробую как предложил TheXpert, но то что терминал выгружает dll сразу, не  зависимо от DLL_PROCESS_DETACH, это наверно и есть ошибка терминала.

TheXpert:

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

в любом случае то что вы делаете при DLL_PROCESS_DETACH это уже поздно. Сделайте явную функцию deinit в длл которая будет выставлять этот флаг и явно вызываться при завершении сервиса.

Спасибо за подсказку, попробую так сделать.

 
Roman:

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

Попробую как предложил TheXpert, но то что терминал выгружает dll сразу, не  зависимо от DLL_PROCESS_DETACH, это наверно и есть ошибка терминала.

Спасибо за подсказку, попробую так сделать.

А с чего Вы взяли, что dll живет в отдельном потоке? У Вас банальное аварийное завершение работы программы, не обработанное в условиях цикла.

А DllMain запускается при подключении/отключении dll к процессу DLL_PROCESS и при создании/прекращении работы потока, созданного в этом процессе DLL_THREAD. Так что Ваш bool Detach, не факт, что и вообще существует внутри dll, ибо компилятор мог его и убрать в рамках оптимизации, так как в процессе исполнения всех функций во время жизни dll он не меняется и равен false.

 
Vladimir Simakov:

А с чего Вы взяли, что dll живет в отдельном потоке? У Вас банальное аварийное завершение работы программы, не обработанное в условиях цикла.

А DllMain запускается при подключении/отключении dll к процессу DLL_PROCESS и при создании/прекращении работы потока, созданного в этом процессе DLL_THREAD. Так что Ваш bool Detach, не факт, что и вообще существует внутри dll, ибо компилятор мог его и убрать в рамках оптимизации, так как в процессе исполнения всех функций во время жизни dll он не меняется и равен false.

Не где не было сказано, что dll живёт в отдельном потоке.
Это мы с Vict общались, и друг друга поняли о чём речь ))
То что аварийное завершение это понятно, не понятно почему не срабатывает флаг в DLL_PROCESS_DETACH для выхода из цикла while.
А что касается DLL_THREAD, то они вообще не доступны для mql, об этом пишется в этой статье, проверял, действительно не работают.
А вот с компилятором VS как вариант, тоже может быть прикол.
Хотелось бы услышать пояснения компетентных представителей, а не гадать  ))  

 
Roman:
По моему есть проблема с деинициализацией dll в Сервисах, помогите разобраться.
Проблема вот в чём. После нажатия команды "Остановить" в меню Сервиса, терминал почему то не ждёт завершения функции Fn(). 
Преждевременно пытается разорвать связь с dll, вешая терминал или полностью вылетает (закрывается).
Хотя в точке входа DllMain, флаг Detach в DLL_PROCESS_DETACH явно переводит флаг для завершения цикла while. 

Но while не успевает выйти из цикла, чтобы выполнить функции ниже, по дополнительному завершению всех остальных процессов.
И завершить саму функцию Fn().
Функция DestroyFunction(); выступает как проверочная в данном примере.

Содержание dll


Содержание программы Сервис.
Дополнительная задержка по флагу  _StopFlag   не помогает.


 

Так вы же не вернули управление обратно в терминал, "зависли" в "бесконечном" цикле внутри Fn в DLL.
О каком нормальном завершении может идти речь!

Если нужно подобное поведение, то внутри Fn в DLL необходимо запустить отдельный поток с циклом, который останавливать по флагу, который выставляется в отдельной функции FnStop и при DLL_PROCESS_DETACH
 
Ilyas:
Так вы же не вернули управление обратно в терминал, "зависли" в "бесконечном" цикле внутри Fn в DLL.
О каком нормальном завершении может идти речь!

Если нужно подобное поведение, то внутри Fn в DLL необходимо запустить отдельный поток с циклом, который останавливать по флагу, который выставляется в отдельной функции FnStop и при DLL_PROCESS_DETACH

То что не вернул управление обратно, это сделано для примера, это понятно что while нужно запускать в отдельном потоке, чтобы не блочить поток mql.
Но то же поведение получаю когда запускаю while в другом потоке, проблема в DLL_PROCESS_DETACH, этот идентификатор не срабатывает, для имеющегося уже флага Detach.
Да, уже писали, что нужно заводить отдельную экспортируемую функцию, и через неё управлять флагом.
Но так как показано в примере, флаг в DLL_PROCESS_DETACH не срабатывает.
По этому возможно есть ошибка в терминале, логично же, что DLL_PROCESS_DETACH должен выполнять перевод флага в другое состояние.
Цикл while получив это состояние, выходит из цикла, выполняется всё что встречается на пути и завершает саму функцию Fn()
И только после этого должна происходить выгрузка dll  !
Но этого не происходит, получается какая то ранняя выгрузка dll скрытыми механизмами терминала, по этому получаем аварийное завершение.  

[Удален]  
TheXpert:

чтобы в обсуждение багов и конструкций не лезли со своими комментами некомпетентные типа тебя, федосеева и т.д.

чтобы конструкции и механизмы взятые в MQL из С++ целиком и выглядящие так же как в С++ работали так же как в С++.

это бред и ты это знаешь, но тебе ведь набросить надо.

ноешь как раз ты. про то как достали, про отдельный язык и про отдельную ветку.

открой для себя и сочувствующих отдельную ветку и ной там.

Я был о тебе лучшего мнения. Ошибся. Бывает. Ты хам и ... не умный.

 
Roman:

То что не вернул управление обратно, это сделано для примера, это понятно что while нужно запускать в отдельном потоке, чтобы не блочить поток mql.
Но то же поведение получаю когда запускаю while в другом потоке, проблема в DLL_PROCESS_DETACH, этот идентификатор не срабатывает, для имеющегося уже флага Detach.
Да, уже писали, что нужно заводить отдельную экспортируемую функцию, и через неё управлять флагом.
Но так как показано в примере, флаг в DLL_PROCESS_DETACH не срабатывает.
По этому возможно есть ошибка в терминале, логично же, что DLL_PROCESS_DETACH должен выполнять перевод флага в другое состояние.
Цикл while получив это состояние, выходит из цикла, выполняется всё что встречается на пути и завершает саму функцию Fn()
И только после этого должна происходить выгрузка dll  !
Но этого не происходит, получается какая то ранняя выгрузка dll скрытыми механизмами терминала, по этому получаем аварийное завершение.  

Дай угадаю. Если запускаешь из dll цикл в потоке терминала, то зависание, а если в отдельном потоке, которому detach() делаешь, то терминал падает с ошибкой?
 
Roman:

То что не вернул управление обратно, это сделано для примера, это понятно что while нужно запускать в отдельном потоке, чтобы не блочить поток

так приводите сразу правильный пример. и оставьте аттачи детачи в покое. управляйте созданием\удалением потоков явно сами.