Скачать MetaTrader 5

Передача текста ошибки из DLL в EA(MT4)

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Зарегистрируйся, чтобы опубликовать статью и получить 200 USD
traregs
44
traregs 2013.04.05 13:26 

Подскажите, можно ли сдлать в окне сообщений от эксперта в MetaTrader4 вместо:

2013.04.05 17:19:57 Test_Throw EURUSD,H1: function 'Test_Throw' call from dll 'ZZZ.dll' critical error e06d7363 at 750F812F.


что-то вроде:

 

2013.04.05 17:19:57 Test_Throw EURUSD,H1: function 'Test_Throw' call from dll 'ZZZ.dll' critical error: "Index for buffer SomeBufferInsideDLL (17) is out of range (10)".

 соответственно, текст ошибки формируется внутри функции на c++

220Volt
1175
220Volt 2013.04.05 13:50  
DLL:
#include <string.h>
void __stdcall Temp(char *mqlStr)
{
   size_t mqlStringSize = strlen(mqlStr);
   char stroka[] = "DLL string";          // Эту строку передадим в MQL.
   if(strlen(stroka) > mqlStringSize)
      stroka[mqlStringSize] = '\0';       // Добавляем нуль-терминатор (обозначает конец строки).
   strcpy(mqlStr, stroka);
   return;
}

MQL:
#include "name.dll"
void Temp(string str);
#include
int start()
{ 
   string str = "wwwwwsff";    // Задаем длину строки; Если длина будет меньше необходимого, то строка будет урезана.
   Temp(str); 
   Alert(str); 
   return;
} 

Идея в том, чтобы переписать буфер стринга из терминала.  Предварительно нужно заполнить стринг данными. Я этим способом особо не пользовался (не обкатано).

220Volt
1175
220Volt 2013.04.05 14:03  

Я так понимаю, что исключение вылетает, в экспортируемой функции: должно быть:

try
{
        // действия
}
catch(exception &e)
{
        e.what();   // строка с пояснением, ее отсылаем.
}
220Volt
1175
220Volt 2013.04.05 14:08  

Можно еще так:

#include <Windows.h>
void fn()
{
   try
   {
        
   }
   catch(exception &e)
   {
        MessageBoxA(NULL, e.what(), "", MB_OK);
   }
}
Vadim Zhunko
5226
Vadim Zhunko 2013.04.05 15:17  
220Volt:

Можно еще так:

#include <Windows.h>
void fn()
{
   try
   {
        
   }
   catch(exception &e)
   {
        MessageBoxA(NULL, e.what(), "", MB_OK);
   }
}

 

Конечно, только так и надо!

У меня даже класс написан для возврата вразумительного описания ошибки. Там сам пишешь или класс понимает, что системная ошибка есть, возвращает полный путь к точке кода, где это произошло, и полное описание системной ошибки и пользовательские комментарии к ней. 

traregs
44
traregs 2013.04.05 22:50  

Ну это всё про 2 варианта:

1) Вывод сообщения средствами C++ (вообще без терминала MetaTrader4). Не уверен, что это возможно: с чего бы консольное приложение чего-то выводило, не имея своего окна? Честно говоря, я даже и не представляю куда в этой ситуации перенаправлены cerr и cout.

2) Возврат строки через указатель. Ну это - ёжику ясно.

 

Вопрос был - вывести сообщение аварийно. Вернуть строку - это проще пареной репы, НО при крэше - ничего никуда не вернётся! До возврата значения из функци -- просто не дойдёт.

При крэше - в логе  MetaTrader4 будет:

2013.04.05 17:19:57 Test_Throw EURUSD,H1: function 'Test_Throw' call from dll 'ZZZ.dll' critical error e06d7363 at 750F812F.

 Проблема в том, что  "error e06d7363 at 750F812F" - очень не информативно.

 

Если же иметь ввиду ручной вызов throw (при отсутствии реального крэша), то и тут - возврат строки - сложно, мутно и не универсально. А главное - не прерывает дальнейшего выполнения, надо вручную всё отслеживать. Собственно, что я объясняю: мне нужно именно то, зачем и реализован разработчиками языка механизм вызова и обработки исключений. Что такое ручной вызов throw - искусственное прерывание исполнения кода всей программы сразу, а также автоматическая доставка диагностического сообщения.

Задача в том, чтобы в логе терминала MetaTrader4 - отразилось аварийное сообщение инициированое в DLL, и не через Print(MessageFromDLLString);  - а напрямую.

Vadim Zhunko
5226
Vadim Zhunko 2013.04.06 00:34  
Thunderman:

Ну это всё про 2 варианта:

1) Вывод сообщения средствами C++ (вообще без терминала MetaTrader4). Не уверен, что это возможно: с чего бы консольное приложение чего-то выводило, не имея своего окна? Честно говоря, я даже и не представляю куда в этой ситуации перенаправлены cerr и cout.

2) Возврат строки через указатель. Ну это - ёжику ясно.

1. Любое приложение может создавать свои окна и консоли. Даже DLL. Нет консоли - нет потоков, нет вывода в консоль. Но программа продолжает работать.

2. Не могу понять, зачем возвращать указатель?

Открывайте диалоговое окно функцией MessageBox(). Выводите туда любую информацию. Или пишите свой лог из DLL.

220Volt
1175
220Volt 2013.04.06 01:18  
Thunderman:
...

Задача в том, чтобы в логе терминала MetaTrader4 - отразилось аварийное сообщение инициированое в DLL, и не через Print(MessageFromDLLString);  - а напрямую.

Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно, терминал ничего не знает о типах, которые вы (или библиотека) выбрасываете в качестве исключений.

Не могли бы вы расшифровать креш это что?

traregs
44
traregs 2013.04.06 03:01  
220Volt:

Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно, терминал ничего не знает о типах, которые вы (или библиотека) выбрасываете в качестве исключений.

Не могли бы вы расшифровать креш это что?

 

Ну вот - значит невозможно... А крэш - я имел ввиду необработанное исключение вроде деления на ноль, в отличие от генерируемых своим кодом исключений.
220Volt
1175
220Volt 2013.04.06 04:12  

Если MessageBox совсем не устраивает, то можно консоль прикрутить:

void __stdcall fn(void)   // функция в dll
{
        try
        {
                 throw std::invalid_argument("illegal_param");
        }
        catch(std::exception &e)
        {
                if( AllocConsole() )                     // Создаем консоль, у процесса не более одной.
                {
                   // Связываем буферы консоли с предопределенными файловыми описателями.
                   freopen("conin$","r",stdin);
                   freopen("conout$","w",stdout);
                   freopen("conout$","w",stderr);
                }
                std::cout<<e.what();
        }
        // FreeConsole();                               // Удаление консоли
}
Лично я пользуюсь MessageBox'ами и никаких проблем нет.
220Volt
1175
220Volt 2013.04.06 07:07  

На последок:

220Volt:

Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно ...

100% гарантию не даю, мое мнение.
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий