Errores, fallos, preguntas - página 2540

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

¿Qué quieres?

Para que los incompetentes como tú, Fedoseyev, etc. no se metan en la discusión de los bichos y diseños con sus comentarios.

Que las construcciones y mecanismos tomados en MQL de C++ en su totalidad y con el mismo aspecto que en C++ funcionan igual que en C++.

Sergei Tabolin:

¿Para que MQL sea un análogo completo de C++?

es una mierda y lo sabes, pero tienes que lanzarlo ahí.
Sergey Tabolin:

Y deja de quejarte y de soltar mocos por ello. He abierto un hilo aparte para estas "discusiones".

Eres tú el que se queja de lo molesto que es, de un idioma distinto y de un hilo distinto.

Abre un hilo aparte para ti y tus simpatizantes y lloriquea allí.

 
¿Cómo hacer que el terminal libere el archivo mqd? O mejor aún, ¿si hubiera una forma interna de eliminarlo de la interfaz?
 
Stanislav Korotky:
¿Cómo hacer que el terminal libere el archivo mqd? O mejor aún, ¿si hubiera una forma interna de eliminarlo de la interfaz?

Puedo adivinar aproximadamente de qué trata la pregunta. Es mejor reafirmarlo.

 
Creo que hay un problema con la desinicialización de dlls en Servicios, ayúdame a entender.
El problema es este. Después de pulsar el comando "Stop" en el menú de servicio, el terminal no espera a que la función Fn() termine por alguna razón.
Intenta romper prematuramente la conexión con la dll, colgando el terminal o cerrándose completamente (se cierra).
Aunque en el punto de entrada DllMain, la bandera Detach en DLL_PROCESS_DETACH establece explícitamente una bandera para terminar el bucle while.

Pero el while no tiene tiempo de salir del bucle a tiempo para ejecutar las funciones de abajo, después de que todos los otros procesos hayan terminado adicionalmente.
Y terminar la propia función Fn().
La función DestroyFunction(); actúa como un control en este ejemplo.

El contenido de la 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;
}


El contenido del programa Servicio.
El retraso adicional por _StopFlag no ayuda.

//+------------------------------------------------------------------+
//|                                                      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);
}
//+------------------------------------------------------------------+
Archivos adjuntos:
MQL5.zip  54 kb
 
Roman:
Creo que hay un problema con la desinicialización de la dll en Servicios, ayúdame.

la dll no se descarga (necesariamente) inmediatamente después de la finalización del servicio (podría estar equivocado)

En cualquier caso, lo que se hace con DLL_PROCESS_DETACH es demasiado tarde. Haga una función explícita deinit en la dll que establezca esta bandera y la llame explícitamente cuando el servicio termine.

 
Roman:

El terminal comenzará a descargar la lib después de que el hilo regrese de start(), creo. Si no, ¿cómo funciona? ¿El programa se está ejecutando y empieza a romper su entorno? Esto es una tontería. Inicie un hilo separado en la lib, no persiguiendo un hilo de script en un bucle, y podrá terminar normalmente.

 
Vict:

El terminal comenzará a descargar la lib después de que el hilo regrese de start(), creo. Si no, ¿cómo funciona? ¿El programa se está ejecutando y empieza a romper su entorno? Esto es una tontería. Inicie un hilo separado en la lib, y podrá terminar normalmente.

El caso es que tengo el mismo problema con los hilos, y por ello no puedo terminar correctamente otros procesos (hilos), que tienen un montón de objetos que necesitan ser destruidos.
No puedo terminar otros procesos correctamente (es decir, no puedo matar otros procesos).
El Terminal funciona incorrectamente con el punto de salidaDLL_PROCESS_DETACH.

Probaré lo que sugirió TheXpert, pero el hecho de que el terminal descargue la dll inmediatamente, independientemente de DLL_PROCESS_DETACH, debe ser un error del terminal.

TheXpert:

La dll no se descarga (necesariamente) inmediatamente después de la finalización del servicio (podría estar equivocado)

De todos modos, lo que estás haciendo con DLL_PROCESS_DETACH es demasiado tarde. Hacer una función explícita deinit en la dll, que establecerá esta bandera y llamará explícitamente al cierre del servicio.

Gracias por la pista, lo intentaré así.

 
Roman:

El caso es que tengo el mismo problema con los hilos y por ello no puedo terminar correctamente otros procesos (hilos) que tienen un montón de objetos que necesitan ser destruidos.
No puedo terminar otros procesos correctamente (es decir, no puedo hacer nada con ellos).
El Terminal funciona incorrectamente con el punto de salida DLL_PROCESS_DETACH.

Probaré lo que sugirió TheXpert, pero el terminal descarga la dll de golpe, independientemente de DLL_PROCESS_DETACH, debe ser un error del terminal.

Gracias por el consejo, lo probaré así.

¿Qué te hace pensar que el dll vive en un hilo aparte? Tienes un fallo trivial del programa que no se maneja en condiciones de bucle.

Y DllMain se ejecuta al conectar/desconectar la dll al proceso DLL_PROCESS y al crear/terminar el hilo creado en este proceso DLL_THREAD. Así que su bool Detach, no es necesariamente existe dentro de la dll, porque el compilador puede haber eliminado en el marco de la optimización, ya que durante la ejecución de todas las funciones durante la vida de la dll no cambia y es igual a falso.

 
Vladimir Simakov:

¿Qué te hace pensar que el dll vive en un hilo aparte? Tienes un fallo trivial del programa que no se maneja en condiciones de bucle.

Y DllMain se inicia cuando se conecta/desconecta la dll al proceso DLL_PROCESS y cuando se crea/desconecta un hilo, creado en este proceso DLL_THREAD. Así que su bool Detach, no es necesariamente existe dentro de la dll, porque el compilador puede haber eliminado en el marco de la optimización, ya que durante la ejecución de todas las funciones durante la vida de la dll no cambia y es igual a falso.

No se ha dicho en ningún sitio que el dll viva en un hilo aparte.
Nos comunicamos con Vict y nos entendemos )).
Entiendo que es un crash, no entiendo por qué no funciona el flag en DLL_PROCESS_DETACH para salir del bucle while.
En cuanto a DLL_THREAD, no están disponibles para mql en absoluto, está escrito en este artículo, lo he comprobado y realmente no funcionan.
Pero con el compilador VS como opción, podría ser un truco también.
Me gustaría escuchar las explicaciones de los representantes competentes en lugar de adivinar ))

 
Roman:
Creo que hay un problema con la desinicialización de la dll en los Servicios, ayuda a entender.
El problema es este. Después de pulsar el comando "Stop" en el menú de servicio, el terminal no espera a que la función Fn() termine por alguna razón.
Intenta romper prematuramente la conexión con la dll, colgando el terminal o cerrándose completamente (se cierra).
Aunque en el punto de entrada de DllMain, la bandera Detach en DLL_PROCESS_DETACH establece claramente una bandera para terminar el bucle while.

Pero el while no tiene tiempo de salir del bucle a tiempo para ejecutar las funciones de abajo, después de que todos los otros procesos hayan terminado adicionalmente.
Y terminar la propia función Fn().
La función DestroyFunction(); actúa como un control en este ejemplo.

El contenido de la dll


El contenido del programa Servicio.
El retraso adicional por _StopFlag no ayuda.


Así que no recuperó el control de la terminal, se "colgó" en un bucle "sin fin" dentro del Fn en la DLL.
¿De qué tipo de terminación normal estamos hablando?

Si necesita este comportamiento, entonces dentro de Fn en DLL debe ejecutar un hilo separado con bucle, que debe ser detenido por la bandera, que se establece en la función separada FnStop y en DLL_PROCESS_DETACH