Errori, bug, domande - pagina 2577

 
Igor Makanu:

Conosco quell'opzione.

Poi divisione per zero.

 
fxsaber:

Poi divisione per zero.

Ng... c'era speranza, ma come sempre solo hardcore ))))

 
Vict:

ZS: forse non si scherza affatto con le stringhe? salvare gli array in wchar_t e farli correre, e all'interno del µl convertire in stringa se necessario https://www.mql5.com/ru/docs/convert/shortarraytostring

D'accordo

Forum sul trading, sistemi di trading automatico e test di strategia

WinAPI -> MQL5 x64

A100, 2018.05.29 14:11

Tutta la regola è stata detta. Se volete che funzioni sempre - dovete usare ushort, e se volete capire perché la stringa smette improvvisamente di funzionare (ciò che funzionava ieri) - potete usare string

 
Vict:

qui stai andando fuori dai limiti


Mi hai dato l'idea di controllare la lunghezza della stringa inizializzata in StringInit(out, 165, 32);

L'aiuto di StringInit dice che il secondo parametro è la lunghezza della stringa, la lunghezza della stringa nella mia comprensione è il numero di caratteri della stringa.
Nel mio caso, la stringa in arrivo ha 164 caratteri, quindi ho messo 165 nel secondo parametro, e ho provato più di *2, 330.

Usarememcpy_s con un puntatore,

memcpy_s(out, wcslen(data) * sizeof(wchar_t*), data, wcslen(data) * sizeof(wchar_t*));

Il risultato era lo stesso, la fine della stringa va sempre alla deriva per il numero di caratteri, e ci sono perdite durante il parsing.
Senza un puntatore la stringa è anche fluttuante.

Ma mi hai dato un'idea e in StringInit(out, 1400, 32) ho impostato la dimensione del puntatore in byte, non la lunghezza della stringa.
E voilà miracolo, la stringa è diventata senza caratteri di output extra, nessun problema di parsing, e non una sola perdita.
Voglio notare che è con il puntatore in sizeof, senza il puntatore la stringa galleggia.

Questo pone una domanda agli sviluppatori, l'aiuto su StringInit è corretto?
Non si confonde, nell'aiuto o nella funzione StringInit stessa, la lunghezza della stringa con la dimensione della stringa?
In generale ora se usate memcpy funziona correttamente se passate la dimensione del puntatore e StringInit è inizializzato con questa dimensione, non con la lunghezza!

 
A100:

D'accordo

Sì, anch'io sono d'accordo. Ma non è sempre conveniente usare una stringa come array, specialmente quando questa stringa deve essere passata attraverso diverse funzioni.
I puntatori sono più convenienti in questo caso, non c'è bisogno di riempire nuovamente questa matrice in ogni funzione di transito, e inoltre si inserisce un parametro in più per la matrice, la sua dimensione.

 
A100:

Quindi avete semplicemente allocato un buffer che è deliberatamente sovradimensionato (spinto indietro il confine) e l'errore semplicemente non appare - perché era al confine

L'ho pensato anch'io, la lunghezza della corda è 164, impostata 165, impostata 330.
330 non è chiaramente un limite della lunghezza delle stringhe, se si contano le stringhe in caratteri.
Si scopre che non è la lunghezza, ma la dimensione dei byte.
Ma l'aiuto suggerisce il contrario, che dovrebbe essere la lunghezza inStringInit.

In generale, come ho capito il tipo stringa di mql è un puntatore e si dovrebbe gestire questo tipo come un puntatore.

 
Ha anche deciso di controllare la stringa ricevuta nella dll, per la presenza di null terminale.
Lo zero è presente
for (int index = 0; index <= wcslen(data); ++index)
   wcout << static_cast<int>(data[index]) << " ";
123 34 101 34 58 34 97 103 103 84 114 97 100 101 34 44 34 69 34 58 49 53 54 57 54 50 52 50 50 57 50 51 54 44 34 115 34 58 34 66 84 
67 85 83 68 84 34 44 34 97 34 58 49 54 54 50 49 57 49 55 53 44 34 112 34 58 34 56 50 48 50 46 49 48 48 48 48 48 48 48 34 44 34 113 
34 58 34 48 46 48 51 51 50 51 48 48 48 34 44 34 102 34 58 49 56 51 57 54 49 54 55 50 44 34 108 34 58 49 56 51 57 54 49 54 55 50 44 
34 84 34 58 49 53 54 57 54 50 52 50 50 57 50 51 49 44 34 109 34 58 116 114 117 101 44 34 77 34 58 116 114 117 101 125 0
 
Roman:

Se insistete, fate come volete.

 
Roman:

L'ho pensato anch'io, la lunghezza della stringa era 164, l'ho impostata a 165 e poi a 330.
330 non è ovviamente un limite di lunghezza delle stringhe se si contano le stringhe in caratteri.
Si scopre che non è la lunghezza, ma la dimensione dei byte.
Ma l'aiuto suggerisce il contrario, che dovrebbe essere la lunghezza in StringInit.

In generale, come ho capito il tipo stringa di mql è un puntatore e si dovrebbe gestire questo tipo come un puntatore.

La stringa di tipo mql è una struttura che contiene un puntatore, la lunghezza della stringa ed eventualmente qualcos'altro.

Quando si passa una stringa alla DLL, viene passato solo il puntatore. La lunghezza della stringa deve essere passata manualmente.

E assicuratevi sempre di non sovradimensionare la corda.

Tutti i cambiamenti nelle dimensioni della linea sono solo sul lato MQL.

Sul lato DLL, dovreste leggere attentamente l'aiuto per le funzioni che usate. Questo è l'unico problema che avete.

sizeof( wchar_t* ) restituisce la dimensione del puntatore. Non è affatto quello di cui avete bisogno.

 
Koldun Zloy:

La stringa di tipo mql è una struttura che contiene un puntatore, la lunghezza della stringa ed eventualmente qualcos'altro.

Quando si passa una stringa alla DLL, viene passato solo il puntatore. La lunghezza della stringa deve essere passata manualmente.

E assicuratevi sempre di non sovradimensionare la corda.

Tutti i cambiamenti nella dimensione delle stringhe sono solo sul lato MQL.

Sul lato DLL, dovreste leggere attentamente l'aiuto per le funzioni che usate. Questo è l'unico problema che avete.

sizeof( wchar_t* ) restituisce la dimensione del puntatore. Questo non è affatto ciò di cui avete bisogno.

Bene, alloco un buffer per la stringa in uscita e lo inizializzo con degli spazi.
Poi passo questa stringa (puntatore) a dll.

string out;
StringInit(out, 1400, 32);

Func(out);

In dll, i dati wchar_t* sono copiati in out, cioè anche un puntatore. Logicamente non dovrebbero esserci problemi.
Da quanto ho capito dall'aiuto, la funzione StringInit dovrebbe impostare la lunghezza della stringa.
Ma ho ancora qualche problema conla funzione StringInit stessa; ho specificato la lunghezza della stringa ed è diventato strano quando ho indicato la dimensione del puntatore.
Non capisco quale trasferimento manuale della lunghezza delle corde intendi.

E se usate sizeof(wchar_t) senza un puntatore, la stringa inizia a fluttuare con caratteri extra, il che causa problemi di parsing e perdite.
Per passare le stringhe nella dll ho usato l'esempio di Renat, dal suo articolo su come scrivere una dll.
Ma per qualche motivo, se lo passo senza puntatore sizeof(wchar_t), la stringa galleggia, mentre con il puntatore sizeof(wchar_t*) non c'è nessun problema.
Mi sembra logico, sto copiando una stringa come puntatore, quindi la dimensione dovrebbe essere passata al puntatore, non il tipo.

Motivazione: