错误、漏洞、问题 - 页 2540

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

你想要什么?

这样,像你、Fedoseyev等无能的人就不会用他们的评论进入对错误和设计的讨论。

MQL中的结构和机制完全取自C++,并且看起来与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所做的都太晚了。在dll中制作一个明确的deinit函数,它将设置这个标志,并在服务结束时明确地调用它。

[删除]  
Roman:

终端将在线程从start()返回后开始卸载lib,我想。否则,它是如何工作的?程序正在运行并开始破坏其环境?这是无稽之谈。在lib中启动一个单独的线程,而不是在循环中追逐一个脚本线程,这样就能正常终止了。

 
Vict:

终端将在线程从start()返回后开始卸载lib,我想。否则它是如何工作的?程序正在运行并开始破坏其环境?这是无稽之谈。在lib中启动一个单独的线程,它就能正常终止了。

问题是,我对线程也有同样的问题,正因为如此,我不能正确地终止其他进程(线程),这些进程有一堆需要销毁的对象。
我不能正确终止其他进程(即我不能杀死其他进程)。
终端在输出点DLL_PROCESS_DETACH 时工作不正常。

我会试试TheXpert的建议,但事实上,无论DLL_PROCESS_DETACH如何,终端都会立即卸载dll,这一定是终端错误。

TheXpert

服务结束后,dll并不(一定)立即被卸载(我可能是错的)。

总之,你用DLL_PROCESS_DETACH所做的事情已经太晚了。在dll中制作一个明确的函数deinit,它将设置这个标志并在服务关闭时明确调用。

谢谢你的提示,我会这样尝试的。

 
Roman:

问题是,我对线程也有同样的问题,正因为如此,我不能正确地终止其他进程(线程),这些进程有一堆需要销毁的对象。
我不能正确终止其他进程(即我对它们无能为力)。
终端在输出点DLL_PROCESS_DETACH 时工作不正常。

我会尝试TheXpert的建议,但是终端会一次性卸载dll,不管DLL_PROCESS_DETACH,这一定是终端的一个错误。

谢谢你的建议,我将尝试这种方式。

是什么让你认为Dll住在一个单独的线程中?你有一个微不足道的程序崩溃,在循环条件中没有处理。

当连接/断开dll到DLL_PROCESS进程以及创建/终止在该进程中创建的线程DLL_THREAD时,DllMain被运行。所以你的bool Detach,它不一定存在于dll里面,因为编译器可能在优化的框架内删除了它,因为在dll的生命周期 内所有函数的执行过程中,它不会改变,等于false。

 
Vladimir Simakov:

是什么让你认为Dll住在一个单独的线程中?你有一个微不足道的程序崩溃,在循环条件中没有处理。

当你连接/断开dll到进程DLL_PROCESS时,以及当你创建/断开一个线程时,DllMain被启动,该线程是在这个进程中创建的DLL_THREAD。所以你的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中设置。