Ошибки, баги, вопросы - страница 2575

 
Roman:

Память выделена в mql коде как

out и передаётся как указатель на выделенную память, так как string в mql, это wichar_t* в dll

Ой как запущено...

Я не знаю реализацию string, могу только догадываться, но, судя по ошибке, при string out на стеке создается указатель, который инициализируется 0x00000000 и Вы благополучно в dll разыменовываете нулевой указатель.

 
Vladimir Simakov:

Ой как запущено...

Я не знаю реализацию string, могу только догадываться, но, судя по ошибке, при string out на стеке создается указатель, который инициализируется 0x00000000 и Вы благополучно в dll разыменовываете нулевой указатель.

Sorry, StringInit не заметил(((
 
Roman:

Память выделена в mql коде как

out и передаётся как указатель на выделенную память, так как string в mql, это wchar_t* в dll

Саму dll покопай, скорее всего там что-то. Последнее время плотно гоняю данные из mql в сторонние приложения С++/С#, никаких проблем никогда не было.

 
Vladimir Simakov:

Саму dll покопай, скорее всего там что-то. Последнее время плотно гоняю данные из mql в сторонние приложения С++/С#, никаких проблем никогда не было.

В dll всё просто, лишнее убрано для наглядности, показана сама идея

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = getData();  //getData библиотечная функция возвращает const wchar_t*
   wcscpy(out, data);
}

Вывожу результат data  в консоль, все строки в консоли идут чётко без пропусков и без глюков.
Передаю в mql через wcscpy(out, data) начинаются траблы
А если передаю проверочную строку написанную руками

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = L"{\"p\":\"2000\"}";  //проверочная строка
   wcscpy(out, data);
}

То почему то проблем нет.

Хм, а тип string в mql учитывает терминальный ноль wchar_t*  ???

Файлы:
 

Предложение о небольшом расширении возможности события OnTimer()

В данный момент, событие OnTimer() начинает возникать с момента установки периодичности вызова ф-цией EventSetTimer().

Получается, что вот такой советник:

bool timer_set = false;
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
   if (!timer_set)
      {
         // -- имитация включения советника в какое-то
         // -- случайное время
         string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
         if (TimeCurrent() >= D'2019.09.24 3:47:40')
            {
               EventSetTimer(600);
               timer_set = true;
            }
      }
}
//+------------------------------------------------------------------+
void OnTimer()
{
//---
   string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
   printf("Current time: %s", time);
}
//+------------------------------------------------------------------+

Выдает примерно следующее:

QJ      0       07:53:10.369    test_timer (GBPUSD_i,D1)        2019.09.24 03:57:41   Current time: 2019.09.24 03:57:41
NF      0       07:53:11.246    test_timer (GBPUSD_i,D1)        2019.09.24 04:07:41   Current time: 2019.09.24 04:07:41

Однако, часто, для проверки возникновения сигнала, достаточно делать проверку после появления очередного бара.

И получается, что, например, для PERIOD_M15 бар возникнет в 00:15:00, а проверка советником может произойти только в 00:29:59.

Т.е. для более менее стабильных и одинаковых результатов, независимо от времени запуска советника,

придется ставить таймер на более короткие промежутки времени, либо дополнительно использовать OnTick().

Как показали эксперименты, это очень сильно замедляет скорость тестирования в тестере стратегий.

Предложение:

Добавить функцию, которая бы позволила установить начальное время, от которого ведется отсчет для возникновения события OnTimer.

Например, какую-нибудь функцию EventSetTimerFrom(const datetime SinceDT), которая бы позволила подстроить вызов таймера через несколько секунд после нового бара.

 
Roman:

В dll всё просто, лишнее убрано для наглядности, показана сама идея

Вывожу результат data  в консоль, все строки в консоли идут чётко без пропусков и без глюков.
Передаю в mql через wcscpy(out, data) начинаются траблы
А если передаю проверочную строку написанную руками

То почему то проблем нет.

Хм, а тип string в mql учитывает терминальный ноль wchar_t*  ???

А вот эта функция заработала

wcsncpy(out, data, wcslen(data));

Но кривовато, кажется один символ бажит в конце строки, лишняя скобка } то появляется то пропадает.
wcslen(data)+1
wcslen(data)+2
не помогло,
и парсится стало без ошибок, без якобы каких то утечек

вообще не понятно, какая длина или размер, одного символа в mql-овскоком string
в типе string точно присутствует какая то ошибка

И в давнейшей статье в пункте 3.3 Передача и модификация строк, в примере скорее всего допущена ошибка.

_DLLAPI void fnReplaceString(wchar_t *text, wchar_t *from, wchar_t *to)
  {
   wchar_t *cp;
    
   //проверка параметров
   if(text==NULL || from==NULL || to==NULL) return;
   if(wcslen(from)!=wcslen(to))             return;
   
   //поищем подстроку
   if((cp=wcsstr(text,from))==NULL)         return;
   
   //заменим
   memcpy(cp,to,wcslen(to)*sizeof(wchar_t));  //в этой строке должен быть указатель sizeof(wchar_t *)
  }

Возможно, где то в коде терминала, преобразование mql-овского string работает таким же образом, без указателя.

 
Maksim Emeliashin:

установить начальное время, от которого ведется отсчет для возникновения события OnTimer.

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

 
fxsaber:

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

Спасибо, полезная вещь!

Очень странно, конечно, что такой несложный момент не учтен в терминале "из коробки".

 
Roman:

А вот эта функция заработала

Но кривовато, кажется один символ бажит в конце строки, лишняя скобка } то появляется то пропадает.
wcslen(data)+1
wcslen(data)+2
не помогло,
и парсится стало без ошибок, без якобы каких то утечек

вообще не понятно, какая длина или размер, одного символа в mql-овскоком string
в типе string точно присутствует какая то ошибка

И в давнейшей статье в пункте 3.3 Передача и модификация строк, в примере скорее всего допущена ошибка.

Возможно, где то в коде терминала, преобразование mql-овского string работает таким же образом, без указателя.

getData() копай. Сдается мне, что где-то там засада.
 
Roman:

В dll всё просто, лишнее убрано для наглядности, показана сама идея

Прикольные такие примеры у вас, всё убрали, оставили UB (модификация строковых литералов), а все телепатить должны. Если рассчитывайте на какой-то толковый совет, то приведите минимальный рабочий код (на двух сторонах), иначе просто трёп.

Причина обращения: