Erros, bugs, perguntas - página 2540

 
Сергей Таболин:

O que é que pretende?

Para que pessoas incompetentes como você, Fedoseyev, etc. não entrem na discussão de insectos e desenhos com os seus comentários.

Que as construções e mecanismos tomados em MQL de C++ na sua totalidade e com o mesmo aspecto que em C++ funcionam da mesma forma que em C+++.

Sergei Tabolin:

Para a MQL ser um análogo completo de C++?

é uma treta e você sabe disso, mas tem de o atirar para lá.
Sergey Tabolin:

E pára de choramingar e de soprar bolhas de ranho por causa disso. Abri um fio à parte para tais "discussões".

És tu quem se queixa de quão irritante é, de uma língua separada e de um fio à parte.

Abra um fio separado para si e para os seus simpatizantes e lamente-se lá.

 
Como fazer com que o terminal liberte o ficheiro mqd? Ou ainda melhor, se houvesse uma forma interna de o apagar da interface?
 
Stanislav Korotky:
Como fazer com que o terminal liberte o ficheiro mqd? Ou ainda melhor, se houvesse uma forma interna de o remover da interface?

Posso adivinhar aproximadamente sobre o que se trata a pergunta. É melhor reafirmá-lo.

 
Penso que existe um problema com a desinicialização dll nos Serviços, ajude-me a compreender.
O problema é este. Após premir o comando "Stop" no menu Service, o terminal não espera que a função Fn() termine por alguma razão.
Tenta quebrar prematuramente a ligação com a dll, pendurando o terminal ou bloqueia completamente (fecha).
Embora no ponto de entrada do DllMain, a bandeira Detach em DLL_PROCESS_DETACH define explicitamente uma bandeira para terminar o loop while.

Mas embora não tenha tempo de sair do laço a tempo de executar as funções abaixo, depois de todos os outros processos terem sido completados adicionalmente.
E terminar a própria função Fn().
A função DestroyFunction(); a função actua como um controlo neste exemplo.

O conteúdo da dll

#define  EXP extern "C" __declspec(dllexport)

void DestroyFunction(void);
EXP void __stdcall Fn(int num);

bool Detach;

//---------------------------------------------------------------------
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
        switch (ul_reason_for_call)
        {
                case DLL_PROCESS_ATTACH:
                        Detach = false;
                        break;
                case DLL_THREAD_ATTACH:
                        break;
                case DLL_THREAD_DETACH:
                        break;
                case DLL_PROCESS_DETACH:
                        Detach = true;
                        break;
        }
        return TRUE;
}

//---------------------------------------------------------------------
void DestroyFunction()
{
        MessageBoxW(NULL, L"Start DestroyFunction", L"OK", MB_OK);

        return;
}

//---------------------------------------------------------------------
EXP void __stdcall Fn(int num)
{
        int count = num;

        while (Detach == false)
        {
            //Имитация работы цикла
            count++;    

            if (count > 0)
                MessageBoxW(NULL, L"Start While iteration", L"OK", MB_OK);

            Sleep(10000);
        }       

 
        //После нажатия команды "Остановить" в меню Сервис, сюда уже не доходим, так как уже висим, или вылетел терминал.
        DestroyFunction();

        
        return;
}


O conteúdo do serviço do programa.
Atraso adicional por _StopFlag não ajuda.

//+------------------------------------------------------------------+
//|                                                      BugDll.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property service
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs


#import "BugDll.dll"
   void Fn(int num);
#import


//+------------------------------------------------------------------+
//| Service program start function                                   |
//+------------------------------------------------------------------+
int OnStart()
{      
   
   Fn(0);

   if(_StopFlag)
      Sleep(10000);
   
   return(0);
}
//+------------------------------------------------------------------+
Arquivos anexados:
MQL5.zip  54 kb
 
Roman:
Penso que há um problema com a desinicialização do dll nos Serviços, ajude-me.

o dll não é (necessariamente) descarregado imediatamente após o fim do serviço (posso estar errado)

Em qualquer caso, o que se faz com DLL_PROCESS_DETACH é demasiado tarde. Fazer uma função deinit explícita em dll que irá definir esta bandeira e chamá-la explicitamente quando o serviço terminar.

 
Roman:

O terminal começará a descarregar a lib após o retorno do fio desde o início(), penso eu. Caso contrário, como é que funciona? O programa está em execução e começa a quebrar o seu ambiente? Isto é um disparate. Iniciar um fio separado na lib, não perseguindo um fio de script num laço, e poderá terminar normalmente.

 
Vict:

O terminal começará a descarregar a lib após o retorno do fio desde o início(), penso eu. Caso contrário como é que funciona? O programa está em execução e começa a quebrar o seu ambiente? Isto é um disparate. Iniciar um fio separado na lib, e poderá terminar normalmente.

A questão é que tenho o mesmo problema com os fios, e por causa disso não posso terminar correctamente outros processos (fios), que têm um monte de objectos que precisam de ser destruídos.
Não posso terminar outros processos correctamente (ou seja, não posso matar outros processos).
O Terminal funciona incorrectamente com o ponto de saídaDLL_PROCESS_DETACH.

Vou tentar o que TheXpert sugeriu, mas o facto de o terminal descarregar a dll imediatamente, independentemente da DLL_PROCESS_DETACH, deve ser um erro do terminal.

TheXpert:

O dll não é (necessariamente) descarregado imediatamente após o fim do serviço (posso estar errado)

De qualquer modo, o que está a fazer com DLL_PROCESS_DETACH é demasiado tarde. Fazer uma função explícita deinit em dll, que irá definir esta bandeira e chamar explicitamente ao encerramento de serviço.

Obrigado pela dica, vou tentar dessa forma.

 
Roman:

A questão é que tenho o mesmo problema com os fios e, por causa disso, não posso terminar adequadamente outros processos (fios) que têm um monte de objectos que precisam de ser destruídos.
Não posso terminar outros processos correctamente (ou seja, não posso fazer nada sobre eles).
O Terminal funciona incorrectamente com o ponto de saída DLL_PROCESS_DETACH.

Vou tentar o que TheXpert sugeriu, mas o terminal descarrega dll de imediato, independentemente de DLL_PROCESS_DETACH, deve ser um bug de terminal.

Obrigado pela dica, vou tentar dessa forma.

O que o faz pensar que a dll vive num fio separado? Tem uma falha de programa trivial que não é tratada em condições de loop.

E o DllMain é executado ao ligar/desligar a dll ao processo DLL_PROCESS e ao criar/terminalizar a thread criada neste processo DLL_THREAD. Portanto o seu bool Detach, não existe necessariamente dentro do dll, porque o compilador pode tê-lo removido no âmbito da optimização, porque durante a execução de todas as funções durante a vida útil do dll não muda e é igual a falso.

 
Vladimir Simakov:

O que o faz pensar que a dll vive num fio separado? Tem uma falha de programa trivial que não é tratada em condições de loop.

E o DllMain é iniciado quando se liga/desliga a dll ao processo DLL_PROCESS e quando se cria/desliga o fio criado neste processo DLL_THREAD. Portanto o seu bool Detach, não existe necessariamente dentro da dll, porque o compilador pode tê-lo removido no âmbito da optimização, porque durante a execução de todas as funções durante a vida útil da dll não muda e equivale a falso.

Não foi dito em lado nenhum que a dll vive num fio separado.
Comunicamos com a Vitória e entendemo-nos ))).
Compreendo que é um acidente, não compreendo porque é que a bandeira em DLL_PROCESS_DETACH não funciona para sair do loop while.
Quanto à DLL_THREAD, não estão disponíveis para mql, está escrito neste artigo, verifiquei-o e não funcionam mesmo.
Mas com o compilador VS como opção, poderia haver também um truque.
Gostaria de ouvir explicações de representantes competentes em vez de adivinhar ))

 
Roman:
Penso que existe um problema com a desinicialização do dll nos Serviços, ajuda a compreender.
O problema é este. Após premir o comando "Stop" no menu Service, o terminal não espera que a função Fn() termine por alguma razão.
Tenta quebrar prematuramente a ligação com a dll, pendurando o terminal ou bloqueia completamente (fecha).
Embora no ponto de entrada do DllMain, a bandeira Detach em DLL_PROCESS_DETACH define claramente uma bandeira para terminar o loop while.

Mas embora não tenha tempo de sair do laço a tempo de executar as funções abaixo, depois de todos os outros processos terem sido completados adicionalmente.
E terminar a própria função Fn().
A função DestroyFunction(); a função actua como um controlo neste exemplo.

O conteúdo da dll


O conteúdo do serviço do programa.
Atraso adicional por _StopFlag não ajuda.


Assim, não conseguiu o controlo de volta ao terminal, "desligou-se" num loop "interminável" dentro da Fn na DLL.
De que tipo de rescisão normal estamos a falar!

Se precisar de tal comportamento, então dentro de Fn em DLL deve correr um fio separado com laço, que deve ser parado por uma bandeira, que está definida na função separada FnStop e em DLL_PROCESS_DETACH