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; }
Идея в том, чтобы переписать буфер стринга из терминала. Предварительно нужно заполнить стринг данными. Я этим способом особо не пользовался (не обкатано).
Я так понимаю, что исключение вылетает, в экспортируемой функции: должно быть:
try { // действия } catch(exception &e) { e.what(); // строка с пояснением, ее отсылаем. }
Можно еще так:
#include <Windows.h> void fn() { try { } catch(exception &e) { MessageBoxA(NULL, e.what(), "", MB_OK); } }
Можно еще так:
#include <Windows.h> void fn() { try { } catch(exception &e) { MessageBoxA(NULL, e.what(), "", MB_OK); } }
Конечно, только так и надо!
У меня даже класс написан для возврата вразумительного описания ошибки. Там сам пишешь или класс понимает, что системная ошибка есть, возвращает полный путь к точке кода, где это произошло, и полное описание системной ошибки и пользовательские комментарии к ней.
Ну это всё про 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); - а напрямую.
Ну это всё про 2 варианта:
1) Вывод сообщения средствами C++ (вообще без терминала MetaTrader4). Не уверен, что это возможно: с чего бы консольное приложение чего-то выводило, не имея своего окна? Честно говоря, я даже и не представляю куда в этой ситуации перенаправлены cerr и cout.
2) Возврат строки через указатель. Ну это - ёжику ясно.
1. Любое приложение может создавать свои окна и консоли. Даже DLL. Нет консоли - нет потоков, нет вывода в консоль. Но программа продолжает работать.
2. Не могу понять, зачем возвращать указатель?
Открывайте диалоговое окно функцией MessageBox(). Выводите туда любую информацию. Или пишите свой лог из DLL.
...
Задача в том, чтобы в логе терминала MetaTrader4 - отразилось аварийное сообщение инициированое в DLL, и не через Print(MessageFromDLLString); - а напрямую.
Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно, терминал ничего не знает о
типах, которые вы (или библиотека) выбрасываете в качестве исключений.
Не могли бы вы расшифровать креш это что?
Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно, терминал ничего не знает о типах, которые вы (или библиотека) выбрасываете в качестве исключений.
Не могли бы вы расшифровать креш это что?
Если 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'ами и никаких проблем нет.
На последок:
Хотите чтобы, например, в такой ситуации: throw std::invalid_argument("illegal_param") терминал вывел "illegal_param"? Забудте, это невозможно ...
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Подскажите, можно ли сдлать в окне сообщений от эксперта в 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++