Erreurs, bugs, questions - page 2591

 
Ilyas:

1. dans MQL seulement Unicode, c'est pourquoi la taille des caractères est de 2 octets

2. La chaîne est une structure (4 octets de tampon et 8 octets de pointeur).


La copie vers une chaîne de caractères devrait être

Si cela ne fonctionne pas, l'erreur doit être trouvée ailleurs.

Oui, la fonction la plus simple

wcscpy(out, data);

et cause un problème. La ligne est copiée uniformément, mais il y a de grands sauts. C'est-à-dire qu'il y a un retard dans la copie.
C'est pourquoi d'autres fonctions ont été essayées, qui posent également le problème si elles sont utilisées correctement.
Toutes sortes de mutex, recursive_mutex, lock_guard ne résolvent pas le problème du saut.

A cause de cela, je ne sais plus quoi penser, la chaîne de la prise arrive correctement,
Le type de chaîne reçu, wchar_t*, signifie automatiquement qu'elle est codée en Unicode et que chaque caractère de la chaîne est égal à 2 octets (testés).
Mais je ne comprends pas que le pointeur wchar_t* sera copié dans une chaîne de huit et douze octets.
Peut-être que la taille des périphériques binaires de l'OS a une autre influence ? Tout est vérifié sur les versions 64 bits, Windows et Linux.

 

Je ne comprends pas, quelles sont les lacunes ? Les lignes vides ?

Est-ce que vous écrivez depuis tous les fils vers la même ligne MQL ou vers des lignes différentes ?

Quand, dans le code MQL, décidez-vous qu'il y a des données dans la chaîne et qu'elles peuvent être traitées/sorties ?


Si tout est sur une seule ligne, ce qui est faux, alors vous avez besoin d'une section critique du côté de la DLL, qui est accessible à partir de MQL et du compteur de changement de ligne.


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


Il s'agit d'un exemple de schéma et il y aura des sauts de lignes du côté MQL (toutes les lignes n'arriveront pas au MQL, certaines seront écrasées).

 
Ilyas:

Je ne comprends pas, quelles sont les lacunes ? Les lignes vides ?

Est-ce que vous écrivez depuis tous les fils vers la même ligne MQL ou vers des lignes différentes ?

Quand, dans le code MQL, décidez-vous qu'il y a des données dans la chaîne et qu'elles peuvent être traitées/sorties ?


Si tout est sur une seule ligne, ce qui est faux, alors vous avez besoin d'une section critique du côté de la DLL, qui est accessible à partir de MQL et du compteur de changement de ligne.


Pseudo-code de MQL

DLL


Il s'agit d'un exemple de schéma et il y aura des sauts de lignes du côté MQL (toutes les lignes n'arriveront pas au MQL, certaines seront écrasées).

Oui des lignes vides, vous pouvez le voir sur la capture d'écran.
Oui, de tous les fils à une ligne MQL. La création de variables pour la chaîne de caractères à la volée est également problématique.
Si nous ne savons pas à l'avance combien de sources seront impliquées, d'où proviennent les cordes, en d'autres termes, de manière dynamique.
Je pensais également aux sections critiques et je me suis dit que le MQL devrait bloquer une certaine manière de lire. Merci pour l'exemple, je vais y réfléchir.
Mais il s'avère que vous recommandez toujours d'obtenir chaque source de chaîne dans sa propre variable séparée ? Et pas dans une seule variable de MQL.
C'est juste qu'il est plus pratique de travailler avec les données reçues de tous les threads à partir d'une seule variable de type chaîne.
Je pensais que s'il y a un verrou en écriture du côté de la dll, dans MQL la lecture ne nécessite pas de verrou, c'est-à-dire que c'est comme si MQL prenait en compte une telle implémentation de la copie.
Mais même si j'obtiens une chaîne à partir d'un seul fil, j'obtiens toujours des sauts !
Si j'utilise d'autres fonctions de copie avec des paramètres corrects, je n'obtiendrai pas de sauts, qu'il s'agisse d'un ou de plusieurs fils, mais j'obtiendrai toujours une chaîne de caractères inégale.
Si vous utilisez de mauvais paramètres, la chaîne de caractères est égale, mais elle commence à fuir.

Dossiers :
458.png  71 kb
 
Ilyas:

Si c'est moins, c'est bon. En général, le tampon de la chaîne est toujours légèrement plus grand que la chaîne elle-même (mais ce n'est pas un fait !).

Mais si vous écrivez davantage, un plantage du terminal est presque certainement garanti.
Le crash ne se produira probablement pas immédiatement, mais seulement lors de la prochaine opération de mémoire dynamique (redistribution de tableaux ou de tampons de chaînes) ou lors de l'arrêt, lorsque la mémoire utilisée par les programmes MQL est rendue au système.

Alors pourquoi conseillez-vous à un nouveau venu d'utiliser la fonctionwcscpy ?

Il existe des fonctions plus sûres : wcscpy_s, wmemcpy_s.

 

Veuillez expliquer pourquoi, dans le gestionnaire OnCalculate, l'heure de chaque barre nouvellement formée time[0] est en avance sur l'heure du tick que nous demandons à l'aide de la fonction SymbolInfoTick ? Lafonction SymbolInfoTick doit toujours retourner le dernier tick connu.

Je joins un indicateur qui reproduit ce problème dans le testeur en mode sweat.

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

A chaque limite de barre, il y a ce problème.

PS. Et selon la documentation, que OnCalculate est appelé pour tous les ticks sans omission, le volume du tick devrait toujours coïncider avec le compteur de ticks, mais ce n'est pas toujours vrai.
Dossiers :
fake.mq5  2 kb
 
Stanislav Korotky:

Veuillez expliquer pourquoi, dans le gestionnaire OnCalculate, l'heure de chaque barre nouvellement formée time[0] est en avance sur l'heure du tick que nous demandons avec la fonction SymbolInfoTick ? La fonction SymbolInfoTick doit toujours retourner le dernier tick connu.

Je joins un indicateur qui reproduit ce problème dans le testeur en mode sweat.

Sur chaque limite de barre, il y a ce problème.

PS. Cet indicateur présente également un autre problème : il y a un comptage de ticks, et à en juger par la déclaration dans la documentation selon laquelle OnCalculate est appelé pour tous les ticks sans manquer, le volume du tick devrait toujours coïncider avec le compteur de ticks, mais ce n'est pas toujours le cas.

S'il vous plaît, donnez-moi le numéro de construction.

 
Slava:

Veuillez me donner le numéro de construction

2093

 
Stanislav Korotky:

2093

Le problème que vous décrivez a été corrigé dans la version 2155.

 

J'ai trouvé la constante SYMBOL_CHART_MODE_OLD en surbrillance dans l'éditeur.

Bien sûr, ce n'est pas dans ENUM_SYMBOL_CHART_MODE.

Qu'est-ce que c'est ?

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

J'ai trouvé la constante SYMBOL_CHART_MODE_OLD en surbrillance dans l'éditeur.

Bien sûr, ce n'est pas dans ENUM_SYMBOL_CHART_MODE.

Qu'est-ce que c'est ?

Mode graphique préhistorique.

N'a pas été utilisé depuis longtemps