Erros, bugs, perguntas - página 2591

 
Koldun Zloy:

O que acontece se a cadeia copiada for maior ou menor do que o tamanho do buffer atribuído?

Se for mais pequeno não faz mal, normalmente o buffer de cordas é sempre ligeiramente maior do que a própria corda (mas isso não é um facto!)

Mas se escrever mais do que isso, é quase garantido que o terminal irá cair.
E a falha muito provavelmente não acontecerá imediatamente, mas apenas no próximo trabalho com memória dinâmica (reatribuição de matrizes ou de buffers de cordas) ou no encerramento, quando a memória utilizada do programa MQL é devolvida ao sistema

 
Ilyas:

1. Em MQL apenas Unicode, é por isso que o tamanho dos caracteres é de 2 bytes

2. cordel é uma estrutura (4 bytes de tamanho de buffer e 8 bytes de tamanho de ponteiro)


Cópia para cordel deve ser

Se não funcionar, o erro deve ser encontrado noutro lugar

Sim, a função mais simples

wcscpy(out, data);

e causa um problema. A linha é copiada de forma uniforme, mas há grandes saltos. Ou seja, há um atraso na cópia.
É por isso que foram experimentadas outras funções, que também causam o problema se usadas correctamente.
Todos os tipos de mutex, recursive_mutex, lock_guard não resolvem o problema de saltar.

Por causa disto já não sei o que pensar, o fio da tomada vem correctamente,
wchar_t* de cadeia recebida significa automaticamente, que está codificado em Unicode, e cada caracter em cadeia é igual a 2 bytes (testado).
Mas não percebo que o ponteiro wchar_t* será copiado para corda com oito bytes e doze bytes.
Talvez seja o modo bit do SO que o influencia de alguma forma? Tudo é verificado nas versões de 64 bits, Windows e Linux.

 

Não percebo, quais são as lacunas? Linhas em branco?

Escreve de todos os fios para a mesma linha MQL ou para linhas diferentes?

Quando em código MQL decide que há dados na cadeia de caracteres e que estes podem ser processados/resultados ?


Se tudo estiver numa linha, o que está errado, então é necessária uma secção crítica no lado DLL, que é acessível a partir do MQL e do contador de mudança de linha


Pseudo código da 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);
     }
  }


Este é um esquema de exemplo e haverá saltos de linhas do lado do MQL (nem todas as linhas chegarão ao MQL, algumas delas serão sobrescritas)

 
Ilyas:

Não percebo, quais são as lacunas? Linhas em branco?

Escreve de todos os fios para a mesma linha MQL ou para linhas diferentes?

Quando em código MQL decide que há dados na cadeia de caracteres e que estes podem ser processados/resultados ?


Se tudo estiver numa linha, o que está errado, então é necessária uma secção crítica no lado DLL, acessível a partir do MQL e do contador de mudança de linha


Pseudo código da MQL

DLL


Este é um esquema de exemplo e haverá saltos de linhas do lado do MQL (nem todas as linhas chegarão ao MQL, algumas delas serão sobrescritas)

Sim linhas vazias, pode vê-lo na imagem do ecrã.
Sim de todos os fios para uma linha MQL. Uma vez que a criação de variáveis para cordel na mosca também é problemática.
Se não soubermos de antemão quantas fontes estarão envolvidas de onde vêm as cordas, por outras palavras, dinamicamente.
Também estava a pensar em secções críticas e também pensei que a MQL deveria bloquear alguma forma de as ler. Obrigado pelo exemplo, vou reflectir sobre o assunto.
Mas acontece que continua a recomendar que cada fonte de cordas seja incluída na sua própria variável separada? E não em uma variável de MQL.
Só que é mais conveniente trabalhar com dados recebidos de todos os fios de uma variável de corda.
Pensei que se houver um bloqueio de escrita no lado dll, na leitura do MQL não é necessário um bloqueio, ou seja, é como se o MQL tivesse em conta tal implementação de cópia.
Mas mesmo que eu receba um fio de um fio, continuo a receber saltos!
Se eu utilizar outras funções de cópia com parâmetros correctos, não receberei saltos, independentemente de se tratar de um ou vários fios, mas ainda assim receberei uma cadeia de caracteres irregular.
Se utilizar parâmetros errados, a corda é uniforme, mas começa a vazar.

Arquivos anexados:
458.png  71 kb
 
Ilyas:

Se menos estiver OK, normalmente o buffer de cordas é sempre ligeiramente maior do que a própria corda (mas isso não é um facto!)

Mas se escrever mais, um acidente terminal é quase de certeza garantido.
E a falha muito provavelmente não acontecerá imediatamente, mas apenas na próxima operação de memória dinâmica (redistribuição de matrizes ou "string buffers") ou no encerramento, quando a memória usada de programas MQL é devolvida ao sistema

Então porque aconselha um recém-chegado a utilizar a funçãowcscpy?

Existem funções mais seguras: wcscpy_s, wmemcpy_s.

 

Por favor explique porque é que no OnCalculate handler o tempo de cada barra recém-formada[0] está à frente do tempo de tick que solicitamos usando a função SymbolInfoTick? Afunção SymbolInfoTick deve sempre devolver o último tick conhecido.

Estou a anexar um indicador que reproduz este problema no modo de teste em modo de suor.

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

Em cada limite de bar existe este problema.

PS. E de acordo com a documentação, que a OnCalculate é chamada para todas as carraças sem omissão, o volume da carraça deve sempre coincidir com o contador de carraças, mas nem sempre é verdade.
Arquivos anexados:
fake.mq5  2 kb
 
Stanislav Korotky:

Explique por favor porque é que no manipulador OnCalculate o tempo de cada barra recém-formada[0] está à frente do tempo do tick que estamos a pedir com a função SymbolInfoTick? A função SymbolInfoTick deve sempre devolver o último tick conhecido.

Estou a anexar um indicador que reproduz este problema no modo de teste em modo de suor.

Em cada limite de bar existe este problema.

PS. Também este indicador demonstra outro problema: há contagem de carraças, e a julgar pela afirmação na documentação de que a OnCalculate é chamada para todas as carraças sem faltar, o volume da carraça deve sempre coincidir com o contador de carraças, mas nem sempre é este o caso.

Por favor, dê-me o número de construção.

 
Slava:

Por favor, dê-me o número de construção

2093

 
Stanislav Korotky:

2093

O problema que descreveu foi resolvido no build 2155

 

Encontrei a constante em destaque SYMBOL_CHART_MODE_OLD no editor.

Claro que não está em ENUM_SYMBOL_CHART_MODE.

O que é isso?

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