Discussione sull’articolo "Comunicare con MetaTrader 5 utilizzando pipe denominate senza utilizzare DLL" - pagina 4

 
Renat:
Quando si trasmettono stringhe, 4 byte della loro dimensione vanno per primi.

Corretta la funzione di ricezione dei dati con la specificazione della dimensione esplicita del buffer.

Ho capito il motivo per cui il trasferimento inverso non funzionava: non avevo specificato la lunghezza dei dati trasferiti.

Grazie mille. Tutto ha funzionato.

Le pipe sono potenti. Rispetto per l'autore dell'articolo.

 
Renat:
È stato fatto nell'ultima build di MetaTrader 4.
Mi scuso, pensavo di essermi perso qualcosa. Ho dato un'occhiata all'annuncio 445 - in effetti si parla di pips. La domanda è che non c'è nessuna parola al riguardo nella guida. Ci saranno aggiornamenti su questo argomento e quando? Forse potete descriverlo nel forum.
 

Le pipe in 4 funzionano in modo simile a quelle in 5, anche attraverso operazioni su file.

Pubblicheremo un articolo per la MT4.

 
Renat:

Le pipe in 4 funzionano in modo simile a quelle in 5, anche attraverso operazioni su file.

Pubblicheremo un articolo per la MT4.

Salve, posso avere un semplice esempio per MT4? Non conto su un articolo, ovviamente.

Mi interessa in particolare sapere come leggere tre parametri dal mio programma scritto in proprio in un Expert Advisor nel terminale.

 
Renat:
È stato realizzato nell'ultima build di MetaTrader 4.

Tutto sembra funzionare bene su MT5.

L'unico punto:

  • Sarebbe opportuno fare in modo che quando si tenta di leggere dal canale utilizzando ReadString e altri metodi, venga prima verificata l'integrità del canale pipe.

Altrimenti, ci si blocca nel metodo WaitForRead per un tempo indefinito, anche se il lato server è chiuso da molto tempo. Tutto questo è stato verificato con Win7-64.

Ho aggiunto il timeout e alcuni altri trucchi al metodo WaitForRead sul lato server e ho ottenuto un sistema funzionante con ricollegamenti automatici su entrambi i lati del canale,

ma è tutto un po' "macchinoso".

 
Dima_S:

Tutto sembra funzionare bene su MT5.

L'unico punto:

  • Sarebbe opportuno fare in modo che quando si tenta di leggere dal canale utilizzando ReadString e altri metodi, venga prima verificata l'integrità del canale pipe.

Altrimenti, ci si blocca nel metodo WaitForRead per un tempo indefinito, anche se il lato server è chiuso da molto tempo. Tutto questo è stato verificato con Win7-64.

Ho aggiunto il timeout e alcuni altri trucchi al metodo WaitForRead sul lato server e ho ottenuto un sistema funzionante con ricollegamenti automatici su entrambi i lati del canale,

ma è tutto un po' "macchinoso".

Da parte nostra è stata una dimostrazione della possibilità di farlo.

Si prega di pubblicare la propria variante della classe. Noi completeremo la classe standard.

 
In realtà, ho aggiunto solo il metodo WaitForRead con controllo degli errori e uscita per timeout (tempo di attesa - in unità convenzionali - numero di intervalli di circa 20 msec):
bool
CFilePipe::WaitForRead( const ulong size, const int _time_out )
{
  int  count = 0;

  while( count < _time_out && m_handle != INVALID_HANDLE && !IsStopped( ))
  {
    if( FileSize( m_handle ) >= size )
    {
     return( true );
    }
    else if( GetLastError( ) != 0 )
    {
      return( false );
    }
    Sleep( 1 );
    count++;
  }

  return( false );
}


La parte del client si presenta più o meno così:

while( !IsStopped( ))
{
// Tentativo di connessione al server PIPE:
  Print( "Try to connect" );
  if( pipe_Ptr.Open( ch_name, FILE_READ | FILE_WRITE | FILE_ANSI ) != INVALID_HANDLE )
  {
    if( IsStopped( ))
    {
      pipe_Ptr.Close( );
      return;
    }
    Print( "Pipe " + ch_name + " opened" );

// Ciclo di ricezione dei dati:
    while( !IsStopped( ))
    {
// Verificare l'integrità della connessione:
      if( !pipe_Ptr.WriteString( "@" ))
      {
        Print( "Disconnected: ", GetLastError( ));
        pipe_Ptr.Close( );
        break;
      }

// Recupero dei dati:
      if( pipe_Ptr.WaitForRead( sizeof( int ), 100 ))
      {
        if( !pipe_Ptr.ReadString( str ))
        {
          Print( "Reading string failed: ", GetLastError( ));
          pipe_Ptr.Close( );
          break;
        }
        Print( "Server: ", str, " received" );
      }
    }
  }
  Sleep( 1000 );
}

Il punto è che il metodo FileSize, che viene usato mentre si attende l'arrivo dei dati, non rileva una violazione della connessione (apparentemente non la controlla).

Il timeout aiuta, ma IMHO non in tutte le situazioni possibili. Sarebbe opportuno controllare tutti questi errori nel metodo FileSize.

 

Strano...

Le immagini del buffer non entrano nei commenti e se si usa alt+PrntScr e si incolla nell'editor, l'immagine viene inserita ma il messaggio non entra nel ramo.

Ok, il problema è che l'esempio di test dell'articolo non va a buon fine.

Ma nel terminale lo script non registra nulla finché non lo cancello dal grafico.

e poi vedo nel log

2013.03.26 15:33:11     PipeClient (EURUSD,M5)  Client: sending welcome message failed
2013.03.26 15:33:11     PipeClient (EURUSD,M5)  Client: pipe opened

Win7x64 build 787 del 21 marzo 2013

 

Ho appena controllato, tutto funziona.


In MQ5 è sufficiente sostituire la linea

uint items=ExtPipe.ReadDoubleArray(buffer);

на 

uint items=ExtPipe.ReadArray(buffer);
 
Renat:

Ho appena controllato, tutto funziona.


Nell'MQ5 è sufficiente sostituire la linea

Non ho ...

Ho sostituito la riga o non avrebbe compilato.