Errores, fallos, preguntas - página 2577

 
Igor Makanu:

Conozco esa opción.

Luego, la división por cero.

 
fxsaber:

Luego, la división por cero.

Np... había esperanza, pero como siempre sólo el hardcore ))))

 
Vict:

ZS: tal vez no te metas con las cadenas en absoluto? guarda las matrices en wchar_t y compite con ellas, y dentro de la µl convierte a cadena si es necesario https://www.mql5.com/ru/docs/convert/shortarraytostring

De acuerdo

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

WinAPI -> MQL5 x64

A100, 2018.05.29 14:11

Ya se ha dicho toda la regla. Si quieres que funcione siempre - tienes que usar ushort, y si quieres entender por qué la cadena deja de funcionar de repente (lo que funcionaba ayer) - puedes usar string

 
Vict:

aquí se está saliendo de los límites


Me has dado la idea de comprobar la longitud de la cadena inicializada en StringInit(out, 165, 32);

La ayuda de StringInit dice que el segundo parámetro es la longitud de la cadena, la longitud de la cadena a mi entender es el número de caracteres de la cadena.
En mi caso, la cadena entrante tiene 164 caracteres, así que puse 165 en el segundo parámetro, y probé más de *2, 330.

Usandomemcpy_s con un puntero,

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

El resultado fue el mismo, el final de la cadena siempre se desvía por el número de caracteres, y hay fugas al parsear.
Sin un puntero la cadena también es flotante.

Pero me has dado una idea y en StringInit(out, 1400, 32) he puesto el tamaño del puntero en bytes, no la longitud de la cadena.
Y voila milagro, la cadena se convirtió sin caracteres de salida extra, sin problemas de análisis, y ni una sola fuga.
Quiero hacer notar que es con el puntero en sizeof, sin el puntero la cadena flota.

Esto plantea una pregunta a los desarrolladores, ¿es correcta la ayuda en StringInit?
¿No se confunde, en la ayuda o en la propia función StringInit, la longitud de la cadena con el tamaño de la misma?
En general ahora si usas memcpy funciona correctamente si pasas el tamaño del puntero y StringInit se inicializa con este tamaño, ¡no con la longitud!

 
A100:

De acuerdo

Sí, yo también estoy de acuerdo. Pero no siempre es conveniente utilizar la cadena como un array, especialmente cuando esta cadena debe ser pasada por varias funciones.
Los punteros en este caso son más convenientes, no es necesario volver a llenar este array en cada función de tránsito, y además introducir otro parámetro para el array, su tamaño.

 
A100:

Así que simplemente has asignado un búfer que está deliberadamente sobredimensionado (empujando hacia atrás el límite) y el error simplemente no aparece - porque estaba en el límite

Yo también lo creía, la longitud de la cuerda es de 164, ajustada 165, ajustada 330.
Está claro que 330 no es un límite de longitud de cadena, si se cuentan las cadenas en caracteres.
Resulta que no es la longitud, sino el tamaño de los bytes.
Pero la ayuda sugiere lo contrario, que debería ser la longitud enStringInit.

En general, según he entendido el tipo de cadena de mql es un puntero y debes manejar este tipo como un puntero.

 
También se decidió comprobar la cadena recibida en la dll, para la presencia de null terminal.
El cero está 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:

Si insistes, hazlo a tu manera.

 
Roman:

Yo también lo pensé. La longitud de la cuerda era de 164, la puse en 165 y luego en 330.
Es evidente que 330 no es un límite de longitud de cadena si se cuentan las cadenas en caracteres.
Resulta que no es la longitud, sino el tamaño de los bytes.
Pero la ayuda sugiere lo contrario, que debería ser la longitud en StringInit.

En general, según he entendido el tipo de cadena de mql es un puntero y debes manejar este tipo como un puntero.

La cadena de tipo mql es una estructura que contiene un puntero, la longitud de la cadena y posiblemente algo más.

Cuando se pasa una cadena a la DLL, sólo se pasa el puntero. La longitud de la cadena debe introducirse manualmente.

Y asegúrese siempre de no sobredimensionar la cuerda.

Todos los cambios en el tamaño de la cadena son sólo en el lado MQL.

En cuanto a la DLL, debes leer detenidamente la ayuda de las funciones que utilices. Este es el único problema que tienes.

sizeof( wchar_t* ) devuelve el tamaño del puntero. Eso no es lo que necesitas en absoluto.

 
Koldun Zloy:

La cadena de tipo mql es una estructura que contiene un puntero, la longitud de la cadena y posiblemente algo más.

Cuando se pasa una cadena a la DLL, sólo se pasa el puntero. La longitud de la cadena debe introducirse manualmente.

Y asegúrate siempre de no sobredimensionar la cuerda.

Todos los cambios en el tamaño de la cadena son sólo en el lado MQL.

En cuanto a la DLL, debe leer detenidamente la ayuda de las funciones que utiliza. Este es el único problema que tienes.

sizeof( wchar_t* ) devuelve el tamaño del puntero. Esto no es lo que necesitas en absoluto.

Bien, asigno un buffer para la cadena de salida, y lo inicializo con espacios.
Luego paso esta cadena (puntero) a la dll.

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

Func(out);

En la dll, los datos de wchar_t* se copian a out, es decir, también un puntero. Lógicamente no debería haber problemas.
Según entiendo en la ayuda, la función StringInit debería establecer la longitud de la cadena.
Pero todavía tengo algunos problemas conla función StringInit en sí; especifiqué la longitud de la cadena y se me hizo raro cuando señalé el tamaño del puntero.
No entiendo a qué transferencia de longitud de cuerda manual te refieres.

Y si usas sizeof(wchar_t) sin un puntero, la cadena empieza a flotar con caracteres extra, lo que causa problemas de parseo y fuga.
Para pasar cadenas a la dll he utilizado el ejemplo de Renat, de su artículo sobre cómo escribir una dll.
Pero por alguna razón, si lo paso sin el puntero sizeof(wchar_t), la cadena flota, mientras que con el puntero sizeof(wchar_t*) no hay problema.
Me parece lógico, estoy copiando una cadena como puntero, el tamaño debería pasarse al puntero, no al tipo.