오류, 버그, 질문 - 페이지 2540

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

무엇을 원하세요?

당신, Fedoseev 등과 같은 무능한 사람들이 그들의 의견으로 버그와 디자인에 대한 토론에 끼어들지 않도록.

전체적으로 C++에서 MQL로 가져오고 C++에서와 동일하게 보이는 구성 및 메커니즘이 C++에서와 동일한 방식으로 작동하도록 합니다.

세르게이 타볼린 :

MQL이 C++의 완전한 아날로그가 되려면?

이것은 말도 안되는 소리이고 당신도 알고 있지만 버려야 합니다.
세르게이 타볼린 :

그리고 이것에 대해 징징거리고 콧물을 붓는 것을 그만 두십시오. 나는 그러한 "토론"에 대해 별도의 주제를 열었습니다.

너만 징징거려 그들이 그것을 어떻게 얻었는지, 별도의 언어와 별도의 지점에 대해.

너 자신과 동정하는 사람들과 거기에 노아를 위해 별도의 지점을 엽니 다.

 
터미널에서 mqd 파일을 강제로 해제하는 방법은 무엇입니까? 아니면 인터페이스에서 정기적으로 제거하는 방법이 있다면 더 좋습니까?
 
Stanislav Korotky :
터미널에서 mqd 파일을 강제로 해제하는 방법은 무엇입니까? 아니면 인터페이스에서 정기적으로 제거하는 방법이 있다면 더 좋습니까?

대략적인 질문이 무엇인지 짐작이 갑니다. 더 나은 재구성.

 
제 생각에는 서비스의 dll 초기화 해제에 문제가 있습니다. 해결하도록 도와주세요.
문제는 이것입니다. 서비스 메뉴에서 "중지" 명령을 누른 후 터미널은 어떤 이유로 Fn() 함수가 완료될 때까지 기다리지 않습니다.
성급하게 dll과의 연결을 끊거나 터미널을 끊거나 완전히 충돌(닫힘)하려고 합니다.
DllMain 진입점에 있는 동안 DLL_PROCESS_DETACH의 Detach 플래그는 while 루프를 종료하도록 플래그를 명시적으로 설정합니다.

그러나 while은 다른 모든 프로세스를 추가로 완료한 후 아래 기능을 실행하기 위해 루프를 종료할 시간이 없습니다.
그리고 Fn() 함수 자체를 완성합니다.
DestroyFunction(); 이 예에서 테스트 역할을 합니다.

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 ;
}


프로그램 서비스의 내용.
_StopFlag 플래그에 대한 추가 지연은 도움이 되지 않습니다.

 //+------------------------------------------------------------------+
//|                                                      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 );
}
//+------------------------------------------------------------------+
파일:
MQL5.zip  54 kb
 
Roman :
제 생각에는 서비스의 dll 초기화 해제에 문제가 있습니다. 해결하도록 도와주세요.

dll은 서비스 종료 직후에 (필연적으로) 언로드되지 않습니다 (틀릴 수 있음)

어쨌든 DLL_PROCESS_DETACH로 하는 일은 이미 너무 늦었습니다. 이 플래그를 설정하고 서비스가 종료될 때 명시적으로 호출되는 명시적 deinit 함수를 dll에서 만드십시오.

 
Roman :

스트림이 start()에서 반환된 후 터미널은 lib 언로드를 시작한다고 생각합니다. 어떻게 작동합니까? 프로그램이 작동하고 환경을 파괴하기 시작합니까? 말도 안돼 루프에서 스크립트 스레드를 쫓지 않고 라이브러리에서 별도의 스레드를 실행하면 이제 정상적으로 완료할 수 있습니다.

 
Vict :

스트림이 start()에서 반환된 후 터미널은 lib 언로드를 시작한다고 생각합니다. 어떻게 작동합니까? 프로그램이 작동하고 환경을 파괴하기 시작합니까? 말도 안돼 라이브러리에서 별도의 스레드를 시작하면 이제 정상적으로 완료할 수 있습니다.

문제는 스레드에서 동일한 문제가 발생하기 때문에 파괴해야 하는 개체가 많은 다른 프로세스(스레드)를 올바르게 종료할 수 없다는 것입니다.
그래서 위와 같이 간단한 예제를 만들어 보았는데 문제가 전혀 다른 것으로 판명되었습니다.
터미널이 종료점 DLL_PROCESS_DETACH 와 함께 올바르게 작동하지 않습니다.

TheXpert에서 제안한 대로 시도해 보겠습니다. 하지만 터미널이 DLL_PROCESS_DETACH에 관계없이 dll을 즉시 언로드한다는 사실은 아마도 터미널 오류일 것입니다.

더엑스퍼트 :

dll은 서비스 종료 직후에 (필연적으로) 언로드되지 않습니다 (틀릴 수 있음)

어쨌든 DLL_PROCESS_DETACH로 하는 일은 이미 너무 늦었습니다. 이 플래그를 설정하고 서비스가 종료될 때 명시적으로 호출되는 명시적 deinit 함수를 dll에서 만드십시오.

팁 감사합니다 시도해보겠습니다.

 
Roman :

문제는 스레드에서 동일한 문제가 발생하기 때문에 파괴해야 하는 개체가 많은 다른 프로세스(스레드)를 올바르게 종료할 수 없다는 것입니다.
그래서 위와 같이 간단한 예제를 만들어 보았는데 문제가 전혀 다른 것으로 판명되었습니다.
터미널이 종료점 DLL_PROCESS_DETACH 와 함께 올바르게 작동하지 않습니다.

TheXpert가 제안한 대로 시도해 보겠습니다. 하지만 터미널이 DLL_PROCESS_DETACH에 관계없이 dll을 즉시 언로드한다는 사실은 아마도 터미널 오류일 것입니다.

팁 감사합니다 시도해보겠습니다.

그리고 dll이 별도의 스레드에 있다는 아이디어는 어디서 얻었습니까? 주기 조건에서 처리되지 않은 프로그램의 평범한 비상 종료가 있습니다.

그리고 DLL_PROCESS 프로세스에 dll이 연결/연결 해제될 때와 이 DLL_THREAD 프로세스에서 생성된 스레드가 생성/종료될 때 DllMain이 실행됩니다. 따라서 bool Detach는 dll 내부에 존재한다는 사실이 아니라 컴파일러가 최적화의 일부로 이를 제거할 수 있기 때문에 dll 의 수명 동안 모든 기능을 실행하는 동안 변경되지 않고 false와 동일하기 때문입니다. .

 
Vladimir Simakov :

그리고 dll이 별도의 스레드에 있다는 아이디어는 어디서 얻었습니까? 주기 조건에서 처리되지 않은 프로그램의 평범한 비상 종료가 있습니다.

그리고 DLL_PROCESS 프로세스에 dll이 연결/연결 해제될 때와 이 DLL_THREAD 프로세스에서 생성된 스레드가 생성/종료될 때 DllMain이 실행됩니다. 따라서 bool Detach는 dll 내부에 존재한다는 사실이 아니라 컴파일러가 최적화의 일부로 이를 제거할 수 있기 때문에 dll 의 수명 동안 모든 기능을 실행하는 동안 변경되지 않고 false와 동일하기 때문입니다. .

어디에도 dll이 별도의 스레드에 있다고 말한 적이 없습니다.
빅트와 나 이야기를 나누었고, 우리는 우리가 무슨 말을 하는지 이해했다))
충돌을 이해할 수 있다는 사실은 왜 DLL_PROCESS_DETACH의 플래그가 while 루프를 종료하기 위해 작동하지 않는지 명확하지 않습니다.
DLL_THREAD의 경우 mql에서 전혀 사용할 수 없습니다 . 이것은 이 기사에 작성되었으며 실제로 작동하지 않는지 확인했습니다.
그러나 VS 컴파일러를 옵션으로 사용하면 재미있을 수도 있습니다.
유능한 담당자의 설명을 듣고 싶습니다. 추측이 아닙니다))

 
Roman :
제 생각에는 서비스의 dll 초기화 해제에 문제가 있습니다. 해결하도록 도와주세요.
문제는 이것입니다. 서비스 메뉴에서 "중지" 명령을 누른 후 터미널은 어떤 이유로 Fn() 함수가 완료될 때까지 기다리지 않습니다.
성급하게 dll과의 연결을 끊거나 터미널을 끊거나 완전히 충돌(닫힘)하려고 합니다.
DllMain 진입점에 있는 동안 DLL_PROCESS_DETACH의 Detach 플래그는 while 루프를 종료하도록 플래그를 명시적으로 설정합니다.

그러나 while은 다른 모든 프로세스를 추가로 완료한 후 아래 기능을 실행하기 위해 루프를 종료할 시간이 없습니다.
그리고 Fn() 함수 자체를 완성합니다.
DestroyFunction(); 이 예에서 테스트 역할을 합니다.

DLL 내용


프로그램 서비스의 내용.
_StopFlag 플래그에 대한 추가 지연은 도움이 되지 않습니다.


따라서 제어를 터미널로 다시 반환하지 않고 DLL의 Fn 내부에 "무한" 루프에 "매달"했습니다.
이 얼마나 평범한 결말인가!

이러한 동작이 필요한 경우 DLL의 Fn 내부에서 별도의 FnStop 함수에 설정된 플래그에 의해 중지될 수 있는 주기로 별도의 스레드를 시작해야 하고 DLL_PROCESS_DETACH