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

 
Roman:

@Ilyas

Из dll, указатель на строку const wchar_t* копирует ровную строку, вот с такими параметрами

С такими параметрами, естественно течёт.

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


И вот такой тест

Показывает следующее

Чаровский символ ' ' возращает два байта, вместо одного. Наверно из за того, что в Unicode. 
А стринги вообще по двенадцать, вместо двух байт, если сравнивать с wchar_t

Как возможный вариант, может где то выравнивание по старшему типу кривит размер стринга?


1. в MQL только юникод, поэтому и размер символа 2 байта

2. cтрока это структура (4 байта размер буфера и 8 байт указатель)


Копирование в строку должно быть таким

wcscpy(out,data);

Если это не работает, то ошибку надо искать в другом месте

 
Nikolay Kositsin:
Всем привет! Похож, что функция ResourceReadImage() при получении данных из BMP файлов работает некорректно! Нарисовал скрипт для отрисовки картинки, как фона на канве. Если картинку достаём с файла, лежащего на жёстком диске и просто заливаем на канву, то всё работает нормально, но если мы достаём пикселы картинки из BMP ресурса, который находится в самом ex5 файле, с помощью функции ResourceReadImage(), то итоговое фоновое изображение такое, словно это махонький  и сильно увеличенный кусочек исходной картинки. В чём причина?

Цикл копирования точек неправильный, замените его на

//--- заливаем фон из массива на канву
   for(int y1=0; y1<height && !IsStopped(); y1++)
      for(int x1=0; x1<width; x1++)
        {
         canvas.PixelSet(x1,y1,bmp_data[y1*width+x1]);
        }
 

А такой вопрос - как получить список input-переменных, такой же, как приходит в функции  FrameInputs(), но только в одном проходе, без оптимизации ?

Вроде как такой вопрос совсем недавно всплывал, я его как-то совсем упустил из виду, а теперь у самого возникла такая задача (хочу делать автоматически set-файлы).

В какую сторону копать ? И если кто помнит то обсуждение - где оно (я найти не могу) ?

Можно, конечно, в каждом эксперте писать одтельную функцию, которая будет создавать такой список, но лучше была бы универсальная библиотечная.
 
Georgiy Merts:

Можно, конечно, в каждом эксперте писать одтельную функцию, которая будет создавать такой список, но лучше была бы универсальная библиотечная.

Посмотрите здесь.

 
fxsaber:

Посмотрите здесь.

Во, точно, оно !

Премного благодарен.

[Удален]  
Ilyas:

1. в MQL только юникод, поэтому и размер символа 2 байта

2. cтрока это структура (4 байта размер буфера и 8 байт указатель)


Копирование в строку должно быть таким

Если это не работает, то ошибку надо искать в другом месте

А что будет, если размер копируемой строки будет больше или меньше, чем размер выделенного буфера?

 
Koldun Zloy:

А что будет, если размер копируемой строки будет больше или меньше, чем размер выделенного буфера?

Если меньше ничего страшного, как правило, буфер строки всегда немного больше чем сама строка (но это не факт!)

А вот в случае, если записать больше, то практически наверняка гарантировано аварийное завершение терминала.
И аварийное завершение скорее всего произойдёт не сразу, а только при следующей работе с динамической памятью (перераспределение массивов или буферов строк) или на завершении работы, когда использованная память MQL программ возвращается в систему

 
Ilyas:

1. в MQL только юникод, поэтому и размер символа 2 байта

2. cтрока это структура (4 байта размер буфера и 8 байт указатель)


Копирование в строку должно быть таким

Если это не работает, то ошибку надо искать в другом месте

Да, самая простая функция 

wcscpy(out, data);

и вызывает проблему. Строка копируется ровная, но идут большие пропуски. То есть задержка в копировании.
По этому и были испробованы другие функции, которые так же вызывают проблему, если использовать их правильно.
Всякие mutex, recursive_mutex, lock_guard не решают проблему пропусков.

По этому уже не знаю куда думать, повторю строка из сокета приходит корректная,
тип получаемой строки wchar_t* автоматом подразумевает что она в кодировке Unicode, и в строке каждый символ равен 2 байтам (проверено).
Но вот как то до меня не доходит, что будет корректное копирование указателя wchar_t* восемь байт, в string двенадцать байт.
Может разрядность OS ещё как то влияет? Всё проверяется на 64 битных версиях, Windows и Linux.

 

Не понятно, что за пропуски ?  Пустые строки ?

Вы из всех потоков в одну MQL строку пишете или в разные ?

Когда в MQL коде решаете, что данные в строке есть и их можно обработать/вывести ?


Если всё в одну строку, что неправильно, то нужна критическая секция на стороне DLL, к которой есть доступ из MQL и счётчик изменений строки


Псевдо код из MQL

#import ...
   bool LockValueIfChanged();
   void UnlockValue();
#import


while(!_IsStopped())
  {
   if(LockValueIfChanged())
     {
      Print( Value );
      UnlockValue();
     }
  }

DLL

uint64_t last_mql_counter=0;
uint64_t counter=0;

bool LockValueIfChanged()
  {
   Lock(cs);

   if(last_mql_counter!=counter)
    {
     last_mql_counter=counter;
     return(true);
    }

   Unlock(cs);
   return(false);
  }

void UnlockValue()
  {
   Unlock(cs);
  }

Thread()
  {
   while( running )
     {
      Lock(cs);

      Value = ...

      counter++;

      Unlock(cs);
     }
  }


Это примерная схема и по ней будут пропуски строк со стороны MQL (не все строки получите в MQL, часть из них будет перезаписана)

 
Ilyas:

Не понятно, что за пропуски ?  Пустые строки ?

Вы из всех потоков в одну MQL строку пишете или в разные ?

Когда в MQL коде решаете, что данные в строке есть и их можно обработать/вывести ?


Если всё в одну строку, что неправильно, то нужна критическая секция на стороне DLL, к которой есть доступ из MQL и счётчик изменений строки


Псевдо код из MQL

DLL


Это примерная схема и по ней будут пропуски строк со стороны MQL (не все строки получите в MQL, часть из них будет перезаписана)

Да пустые строки, на скрине это видно.
Да из всех потоков в одну строку MQL. Так как создание переменных для строки на лету, это тоже проблемное занятие.
Если заранее не известно сколько будет задействовано источников от куда приходят строки , то есть динамически.
За критические секции тоже была мысль, тоже думал что нужно со стороны MQL как то блокировать чтение. Спасибо за пример, буду обдумывать.
Но получается вы всё же рекомендуете каждый источник строки, получать в свою отдельную переменную? А не в одну переменную строки MQL.
Просто из одной переменной строки, удобнее работать с полученными данными из всех потоков.
Я думал что если есть блокировка записи на стороне dll, то в MQL чтение не требует блокировки, то есть в MQL как бы учтена такая реализация копирования. 
Но даже если получать строку из одного потока, то всё равно идут пропуски!
И если использовать другие функции копирования, с правильными параметрами, то пропусков нет, хоть один, хоть несколько потоков, но получается не ровная строка по символам.
Используешь не правильные параметры, строка получается ровная, но начинает течь.

Файлы:
458.png  71 kb