Что за ошибка 4023?

 
Экспериментирую с Dll. Точнее с вызовами функций и разнообразной передачей параметров в Dll. При экспериментах часто получаю недокументированную ошибку 4023. При этом скрипт прерывает свою работу, а вызываемая из Dll функция не отрабатывает. Что означает эта ошибка?
 

 Напиши в поддержку метаквотам. Там тебе ответят точно!

Вот тут https://www.mql5.com/ru/forum/131853 сказано, что такие вопросы нужно посылать:

"Сообщения о багах, глюках, ошибках языка MQL4 и терминала MT4 необходимо посылать через свой профиль на Форуме MQL5. Там принимаются заявки по MT4 и MT5

 
ir0407:
Экспериментирую с Dll. Точнее с вызовами функций и разнообразной передачей параметров в Dll. При экспериментах часто получаю недокументированную ошибку 4023. При этом скрипт прерывает свою работу, а вызываемая из Dll функция не отрабатывает. Что означает эта ошибка?
Тут это обсуждалось, может кто-то нашел ответ.
 
hoz:

 Напиши в поддержку метаквотам. Там тебе ответят точно!

Да были уже попытки. :) Правда давно и не по этой теме. Ответов я тогда так и не получил. И потому писать туда у меня желание давно отпало. Гораздо проще и быстрее решить любой вопрос на общественных форумах, чем обращаться в поддержку.

Вот тут https://www.mql5.com/ru/forum/131853 сказано, что такие вопросы нужно посылать:

"Сообщения о багах, глюках, ошибках языка MQL4 и терминала MT4 необходимо посылать через свой профиль на Форуме MQL5. Там принимаются заявки по MT4 и MT5"

На сколько я понял эти правила, там имеются ввиду "Сообщения о багах, глюках, ошибках языка MQL4 и терминала MT4", которые подразумевают некорректную работу ПО. Т.е. что-то работает не так как ожидалось. В моем же случае, как я понял, все работает корректно и правильно, а вот ошибка 4023, возвращаемая терминалом, просто по каким то причинам не попавшая в документацию, говорит мне о том что я что-то делаю не так. А вот что именно это я и хотел выяснить. Я уже по, результатам своих испытаний, конечно догадываюсь откуда у нее растут ноги и уже даже начал понимать, что примерно она может означать, но хотелось бы услышать мнение действительно знающих людей.
granit77:
Тут это обсуждалось, может кто-то нашел ответ.

Если бы я нашел там ответ то и тему эту не стал бы заводить. Вопросы относительно данной ошибки возникают уже давно. Как в русскоязычном варианте таки в англоязычном. По крайней мере на разных форумах(как англоязычных так и русскоязычных) я находил вопросы по этой ошибке датированные серединой 2006 года, но до сегодняшнего дня ни на один вопрос касаемый ошибки 4023 нет ни одного вразумительного ответа. Поэтому я  решил поднять сей вопрос в отдельной теме.

Впрочем, я и не надеюсь, что получу именно ответ на свой вопрос, а не как обычно флуд со ссылками в поисковики. Хорошо, что хоть на "три веселых" не посылают... :)))

 
Для начала нужен лог из терминала на вызове, импорты функций в mql и объявление функций в длл.
 
TheXpert:
Для начала нужен лог из терминала на вызове, импорты функций в mql и объявление функций в длл.

Ну, от лога никакой пользы нет. Там кроме информации о том, что скрипт загружен и скрипт удален ничего больше нет. (Кстати, отладочные принты тоже почему-то из скрипта в лог не выводятся. Поэтому я дублирую их выводом в комменты на график.) Так же и объявления функций в Dll не играют никакой роли в появлении этой ошибки. Вот привожу текст MQL-скрипта и текст Dll-ки для Delphi.

MQL-cкрипт:

//+------------------------------------------------------------------+
//|                                               Test_MyTestDll.mq4 |
//|                                         Copyright © 2013, ir0407 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2013, ir0407"
#property link      ""

#import "MyTestDll.dll"
  //Эта функция отрабатывает нормально
  int TestStrParam_1(string  TestStr);

  //А вот при попытке обратиться к этой функции возникает
  //ошибка 4023.
  int TestStrParam_2(string &TestStr);
#import

string MyTestStr = "Строка для отправки в Dll";
int Result1, Result2, LastError;
string msg = "";

int deinit()
{
  //LastError = GetLastError();
  if(LastError == 0)
  {
    Print("Скрипт отработал успешно. LastError = ", LastError);
    msg = StringConcatenate(msg, "\nСкрипт отработал успешно. LastError = ", LastError, "\n");
    Comment(msg);
  }
  else
  {
    Print("При работе скрипта возникла ошибка. LastError = ", LastError);
    msg = StringConcatenate(msg, "\nПри работе скрипта возникла ошибка. LastError = ", LastError, "\n");
    Comment(msg);
  }
  return(0);
}


//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
  Print("Попытка вызвать Dll-функцию TestStrParam_1()");
  msg = StringConcatenate(msg, "\nПопытка вызвать Dll-функцию TestStrParam_1()", "\n");
  Comment(msg);

  Result1 = TestStrParam_1(MyTestStr);   //Вызываем функцию
  LastError = GetLastError();

  if(Result1 == StringLen(MyTestStr))
  {
    Print("Dll-функция TestStrParam_1() вызвана успешно, получен результат - ", Result1);
    msg = StringConcatenate(msg, "Dll-функция TestStrParam_1() вызвана успешно, получен результат - ",  Result1,
                                 "; LastError = ", LastError, "\n");
    Comment(msg);
  }
  else
  {
    Print("При вызове Dll-функции TestStrParam_1() возникла ошибка.");
    Print("Вместо ожидаемого результата ", StringLen(MyTestStr), " получен результат - ", Result1);
    msg = StringConcatenate(msg, "При вызове Dll-функции TestStrParam_1() возникла ошибка.\n",
                                 "Вместо ожидаемого результата ", StringLen(MyTestStr),
                                 " получен результат - ", Result1,
                                 "; LastError = ", LastError, "\n");
    Comment(msg);
  }
  
  Print("Попытка вызвать Dll-функцию TestStrParam_2()");
  msg = StringConcatenate(msg, "\nПопытка вызвать Dll-функцию TestStrParam_2()", "\n");
  Comment(msg);

  Result2 = TestStrParam_2(MyTestStr);   //Вызываем функцию
  LastError = GetLastError();

  if(Result2 == StringLen(MyTestStr))
  {
    Print("Dll-функция TestStrParam_2() вызвана успешно, получен результат - ", Result2);
    msg = StringConcatenate(msg, "Dll-функция TestStrParam_2() вызвана успешно, получен результат - ",  Result2,
                                 "; LastError = ", LastError, "\n");
    Comment(msg);
  }
  else
  {
    Print("При вызове Dll-функции TestStrParam_2() возникла ошибка.");
    Print("Вместо ожидаемого результата ", StringLen(MyTestStr), " получен результат - ", Result2);
    msg = StringConcatenate(msg, "При вызове Dll-функции TestStrParam_2() возникла ошибка.\n",
                                 "Вместо ожидаемого результата ", StringLen(MyTestStr),
                                 " получен результат - ", Result2,
                                 "; LastError = ", LastError, "\n");
    Comment(msg);
  }

  return(0);
}
//+------------------------------------------------------------------+

Файл проекта Delphi:

library MyTestDll;

uses
  Unit1 in 'Unit1.pas';

{$R *.res}

begin
end.

И юнит для него:

unit Unit1;

interface

uses SysUtils, Dialogs;

type
  PMQLStr = ^TMQLStr;
  TMQLStr = record
    MQLStrLen: integer;
    MQLStr: PChar;
  end;

  function TestStrParam_1(TestStr: PChar): integer; stdcall;
  function TestStrParam_2(var TestStr: TMQLStr): integer; stdcall;

exports
  TestStrParam_1,
  TestStrParam_2;

implementation

function TestStrParam_1(TestStr: PChar): integer;
begin
  MessageDlg(string(TestStr), mtCustom, [mbOK], 0);
  result:= StrLen(TestStr);
end;

function TestStrParam_2(var TestStr: TMQLStr): integer;
begin
  MessageDlg(string(TestStr.MQLStr), mtCustom, [mbOK], 0);
  result:= StrLen(TestStr.MQLStr);
end;


end.

А это результат работы скрипта.


Причем независимо от того, как я описываю входной параметр для функции в Delphi, я в любом случае получаю ошибку 4023 и функция из Dll не вызывается. Правда есть один интересный момент. Если для второй функции в Delphi сделать описание и содержимое один в один такое же как и у первой функции(естественно что это не правильно), то я все же получаю диалоговое окно, но без текста переданного в Dll. А в MQL на этот вызов я как и обычно получаю ошибку 4023 и возвращаемый результат равен 0.

 

Игорь, MQL не совсем компилятор, он еще немного и интерпретатор. Есть понятие позднего присоединения. или что-то такое. Функции из  библиотек динамического вызова не анализируются "компилятором", а линкуются в процессе исполнения программы. 

Перенесите описание подпрограммы  MQL куда надо и ошибка исчезнет. 

Зачем сыр-бор?  

 
tara:

Игорь, MQL не совсем компилятор, он еще немного и интерпретатор. Есть понятие позднего присоединения. или что-то такое. Функции из  библиотек динамического вызова не анализируются "компилятором", а линкуются в процессе исполнения программы. 

Перенесите описание подпрограммы  MQL куда надо и ошибка исчезнет. 

Зачем сыр-бор?  


Не понял??? :) Что значит перенести куда надо?
 
ir0407:

Не понял??? :) Что значит перенести куда надо?

читай документацию. 
 
А по конкретней... А то мы тут малограмотные, пока носом не ткнут не понимаем. :)
 
ir0407:
А по конкретней... А то мы тут малограмотные, пока носом не ткнут не понимаем. :)

  http://www.delphisources.ru/pages/faq/file_system.html