Errori, bug, domande - pagina 2575

 
Roman:

La memoria è allocata nel codice mql come

fuori e passato come un puntatore alla memoria allocata, poiché la stringa in mql è wichar_t* in dll

Oh, che casino...

Non conosco l'implementazione delle stringhe, posso solo indovinare, ma a giudicare dall'errore, string out crea un puntatore sullo stack che è inizializzato a 0x0000000000 e si dereferenzia tranquillamente un puntatore nullo nella dll.

 
Vladimir Simakov:

Oh, è così complicato...

Non conosco l'implementazione delle stringhe, posso solo indovinare, ma a giudicare dall'errore, string out crea un puntatore sullo stack che è inizializzato a 0x0000000000 e si dereferenzia tranquillamente un puntatore nullo nella dll.

Scusa, non avevo notato StringInit ((((.
 
Roman:

La memoria è allocata nel codice mql come

fuori e passato come puntatore alla memoria allocata, come stringa in mql è wchar_t* in dll

Scavate nel dll stesso, molto probabilmente qualcosa c'è. Ultimamente, ho alimentato dati da mql ad applicazioni C++/C# di terze parti, senza alcun problema.

 
Vladimir Simakov:

Scava nel dll stesso, probabilmente c'è qualcosa lì. Ultimamente, ho alimentato dati da mql ad applicazioni C++/C# di terze parti, senza alcun problema.

Il dll è molto semplice, non è necessario per chiarezza, l'idea stessa è mostrata.

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = getData();  //getData библиотечная функция возвращает const wchar_t*
   wcscpy(out, data);
}

Emettere i dati del risultato alla console, tutte le linee nella console sono chiare, senza interruzioni e senza glitch.
Passo il risultato a mql attraverso wcscpy(out, data), ma ora ho problemi.
Ma se passo una stringa di controllo scritta a mano

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = L"{\"p\":\"2000\"}";  //проверочная строка
   wcscpy(out, data);
}

Non ho problemi per qualche motivo.

Hm, il tipo stringa in mql considera il terminale nullo wchar_t * ?

 

Suggerimento di espandere un po' la possibilità dell'evento OnTimer()

Al momento l'evento OnTimer() inizia a verificarsi quando la periodicità della chiamata è impostata con la funzione EventSetTimer().

Risulta il seguente Expert Advisor:

bool timer_set = false;
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
   if (!timer_set)
      {
         // -- имитация включения советника в какое-то
         // -- случайное время
         string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
         if (TimeCurrent() >= D'2019.09.24 3:47:40')
            {
               EventSetTimer(600);
               timer_set = true;
            }
      }
}
//+------------------------------------------------------------------+
void OnTimer()
{
//---
   string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
   printf("Current time: %s", time);
}
//+------------------------------------------------------------------+

Le uscite sono approssimativamente le seguenti:

QJ      0       07:53:10.369    test_timer (GBPUSD_i,D1)        2019.09.24 03:57:41   Current time: 2019.09.24 03:57:41
NF      0       07:53:11.246    test_timer (GBPUSD_i,D1)        2019.09.24 04:07:41   Current time: 2019.09.24 04:07:41

Tuttavia, spesso è sufficiente controllare la comparsa del segnale dopo l'apparizione di un'altra barra.

Per esempio, risulta che per PERIODO_M15, la barra appare alle 00:15:00, ma il controllo dell'Expert Advisor può controllarla solo alle 00:29:59.

Quindi, per risultati più o meno stabili e uguali, indipendentemente dall'ora di inizio di Expert Advisor,

dovrete impostare un timer per un intervallo di tempo più breve o usare in aggiunta OnTick().

Come hanno dimostrato gli esperimenti, rallenta drammaticamente la velocità di test nello strategy tester.

Suggerimento:

Aggiungere una funzione che permetta di impostare il tempo iniziale a partire dal quale si conta l'evento OnTimer.

Per esempio, qualche funzione EventSetTimerFrom(const datetime SinceDT) che permetterebbe di impostare la chiamata del timer alcuni secondi dopo una nuova barra.

 
Roman:

Il dll è semplice, la roba extra è stata rimossa per chiarezza, l'idea è mostrata.

Incollo il risultato nella console, tutte le linee sono ok, nessuna lacuna, nessun glitch.
Passo il risultato a mql attraverso wcscpy(out, data), ma ora ho problemi.
Se passo una stringa di controllo scritta da me

Non ho problemi per qualche motivo.

Hm, il tipo stringa in mql considera il terminale nullo wchar_t * ?

Ma questa funzione funziona.

wcsncpy(out, data, wcslen(data));

Ma non è del tutto giusto, sembra che ci sia un carattere sbagliato alla fine della stringa, una parentesi extra } appare e poi scompare.
wcslen(dati)+1
wcslen(dati)+2
non ha aiutato,
e viene analizzato senza errori, senza perdite.

nessuna idea su quale sia la lunghezza o la dimensione di un carattere nella stringa mql-looking
c'è sicuramente un errore nel tipo di stringa.

E in un articolo di molto tempo fa, nel paragrafo 3.3 Passare e modificare le stringhe, l'esempio molto probabilmente faceva un errore.

_DLLAPI void fnReplaceString(wchar_t *text, wchar_t *from, wchar_t *to)
  {
   wchar_t *cp;
    
   //проверка параметров
   if(text==NULL || from==NULL || to==NULL) return;
   if(wcslen(from)!=wcslen(to))             return;
   
   //поищем подстроку
   if((cp=wcsstr(text,from))==NULL)         return;
   
   //заменим
   memcpy(cp,to,wcslen(to)*sizeof(wchar_t));  //в этой строке должен быть указатель sizeof(wchar_t *)
  }

Forse da qualche parte nel codice del terminale, la conversione delle stringhe mql funziona allo stesso modo, senza un puntatore.

 
Maksim Emeliashin:

imposta il tempo iniziale dal quale l'evento OnTimer viene contato alla rovescia.

Potete farlo voi stessi attraverso la chiamata ripetuta di EventSetTimer. Notate che nell'account (non nel Tester) il timer galleggia e ha bisogno di una regolazione costante.

 
fxsaber:

Potete farlo voi stessi tramite una chiamata ripetuta a EventSetTimer. Tenete presente che sul conto (non nel Tester) il timer galleggia e ha bisogno di una regolazione costante.

Grazie, cosa utile!

Molto strano, naturalmente, che un punto così semplice non sia preso in considerazione nel terminale "out of the box".

 
Roman:

Ma questa funzione funziona.

Ma sembra essere un po' scomodo, una parentesi extra } appare o scompare alla fine della stringa.
wcslen(dati)+1
wcslen(dati)+2
non ha aiutato,
e viene analizzato senza errori, senza perdite.

nessuna idea su quale sia la lunghezza o la dimensione di un carattere nella stringa mql-looking
c'è sicuramente un errore nel tipo di stringa.

E in un articolo di molto tempo fa, nel paragrafo 3.3 Passare e modificare le stringhe, l'esempio molto probabilmente faceva un errore.

Forse da qualche parte nel codice del terminale, la conversione della stringa mql funziona allo stesso modo, senza il puntatore.

getData() dig. Ho la sensazione che ci sia un problema da qualche parte.
 
Roman:

Il dll è semplice, è stato rimosso per chiarezza e l'idea è mostrata

I tuoi esempi sono divertenti, hai rimosso tutto, lasciato UB (modifica dei letterali di stringa), e tutti devono telepatizzare. Se vi aspettate di ricevere qualche consiglio intelligente, date un minimo di codice funzionante (su due lati), altrimenti è solo spazzatura.