Errors, bugs, questions - page 2591

 
Koldun Zloy:

What happens if the copied string is bigger or smaller than the allocated buffer size?

If it's smaller it's OK, as a rule, the string buffer is always slightly larger than the string itself (but that's not a fact!)

But if you write more than that, it's almost guaranteed that the terminal will crash.
And crash most likely will not happen immediately, but only at next work with dynamic memory (reallocation of arrays or string buffers) or at shutdown, when used MQL program memory is returned to the system

 
Ilyas:

1. in MQL only Unicode, that's why the character size is 2 bytes

2. string is a structure (4 bytes buffer size and 8 bytes pointer size)


Copying to string should be

If it does not work, the error must be found elsewhere

Yes, the simplest function

wcscpy(out, data);

and causes a problem. The line is copied evenly, but there are big skips. That is, there is a delay in copying.
That's why other functions have been tried, which also cause the problem if used correctly.
All sorts of mutex, recursive_mutex, lock_guard do not solve the skipping problem.

Because of this I don't know what to think anymore, the string from the socket comes correctly,
received string type wchar_t* automatically means, that it is Unicode-encoded, and each character in string is equal to 2 bytes (tested).
But somehow I don't get that wchar_t* pointer will copy correctly eight bytes into string twelve bytes.
Maybe it is the bit mode of OS that influences it somehow? Everything is checked on 64-bit versions, Windows and Linux.

 

I don't understand, what are the gaps? Blank lines?

Do you write from all threads to the same MQL line or to different ones?

When in MQL code do you decide that there is data in the string and it can be processed/output ?


If everything is in one line, which is wrong, then you need a critical section on the DLL side, which is accessible from MQL and the line change counter


Pseudo code from 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);
     }
  }


This is an example scheme and there will be skipping of lines from MQL side (not all lines will get to MQL, some of them will be overwritten)

 
Ilyas:

I don't understand, what are the gaps? Blank lines?

Do you write from all threads to the same MQL line or to different ones?

When in MQL code do you decide that there is data in the string and it can be processed/output ?


If everything is in one line, which is wrong, then you need a critical section on the DLL side, which is accessible from MQL and the line change counter


Pseudo code from MQL

DLL


This is an example scheme and there will be skipping of lines from MQL side (not all lines will get to MQL, some of them will be overwritten)

Yes empty lines, you can see it on the screenshot.
Yes from all threads to one MQL line. Since creating variables for the string on the fly is also a problem.
If we don't know beforehand how many sources will be involved where the strings come from, in other words, dynamically.
I was also thinking about critical sections and I also thought that MQL should block some way to read. Thanks for the example, I will think it over.
But it turns out that you still recommend to get each string source in its own separate variable? And not in one variable of MQL.
It's just that it's more convenient to work with received data from all the threads from one string variable.
I thought that if there is a write lock on the dll side, in MQL reading does not require a lock, i.e. it's as if MQL takes into account such a copying implementation.
But even if I get a string from one thread, I still get skips!
If I use other copying functions with correct parameters, I will not get skips, no matter whether it is one or several threads, but I will still get an uneven string of characters.
If you use wrong parameters, the string is even, but it starts leaking.

Files:
458.png  71 kb
 
Ilyas:

If less is OK, usually the string buffer is always slightly larger than the string itself (but this is not a fact!)

But if you write more, a terminal crash is almost certainly guaranteed.
And crash most likely will not happen immediately, but only at next dynamic memory operation (redistributing arrays or string buffers) or at shutdown, when used memory of MQL programs is returned to the system

Then why do you advise a newcomer to usewcscpy function?

There are safer functions: wcscpy_s, wmemcpy_s.

 

Please explain why in the OnCalculate handler the time of each newly formed bar time[0] is ahead of the tick time that we request using the SymbolInfoTick function? TheSymbolInfoTick function should always return the last known tick.

I am attaching an indicator which reproduces this problem in the tester in sweat mode.

2019.10.12 16:51:53.667 2019.01.02 06:00:00   Time 2019.01.02 06:00:00 = 1546408800000 is ahead of tick:  1546297199572
2019.10.12 16:51:53.753 2019.01.02 06:01:00   Time 2019.01.02 06:01:00 = 1546408860000 is ahead of tick:  1546408830000
2019.10.12 16:51:54.315 2019.01.02 06:02:00   Time 2019.01.02 06:02:00 = 1546408920000 is ahead of tick:  1546408919000
2019.10.12 16:51:54.617 2019.01.02 06:03:00   Time 2019.01.02 06:03:00 = 1546408980000 is ahead of tick:  1546408979000

At each bar boundary there is this problem.

PS. And according to the documentation, that OnCalculate is called for all ticks without omission, the tick volume should always coincide with ticks counter, but it's not always true.
Files:
fake.mq5  2 kb
 
Stanislav Korotky:

Please explain why in the OnCalculate handler the time of each newly formed bar time[0] is ahead of the tick time we are requesting with SymbolInfoTick function? The SymbolInfoTick function should always return the last known tick.

I am attaching an indicator which reproduces this problem in the tester in sweat mode.

On each bar boundary there is this problem.

PS. Also this indicator demonstrates another problem: there is tick counting, and judging by the statement in the documentation that OnCalculate is called for all ticks without missing, the tick volume should always coincide with the tick counter, but this is not always the case.

Please give me the build number.

 
Slava:

Please give me the build number

2093

 
Stanislav Korotky:

2093

The problem you described has been fixed in build 2155

 

Found the highlighted constant SYMBOL_CHART_MODE_OLD in the editor.

Of course it is not in ENUM_SYMBOL_CHART_MODE.

What is it?

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Для получения текущей рыночной информации служат функции SymbolInfoInteger(), SymbolInfoDouble() и SymbolInfoString(). В качестве второго параметра этих функций допустимо передавать один из идентификаторов из перечислений ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING соответственно. Некоторые символы (как...