Errores, fallos, preguntas - página 2575

 
Roman:

La memoria se asigna en el código mql como

y se pasa como un puntero a la memoria asignada, ya que string en mql es wichar_t* en dll

Oh, qué desastre...

No conozco la implementación de la cadena, sólo puedo adivinar, pero a juzgar por el error, la cadena hacia fuera crea un puntero en la pila que se inicializa a 0x0000000000 y se dereferencia con seguridad un puntero nulo en la dll.

 
Vladimir Simakov:

Oh, es tan complicado...

No conozco la implementación de la cadena, sólo puedo adivinar, pero a juzgar por el error, la cadena hacia fuera crea un puntero en la pila que se inicializa a 0x0000000000 y se dereferencia con seguridad un puntero nulo en la dll.

Lo siento, no me fijé en StringInit (((.
 
Roman:

La memoria se asigna en el código mql como

y se pasa como un puntero a la memoria asignada, ya que string en mql es wchar_t* en dll

Indague en el propio dll, lo más probable es que haya algo allí. Últimamente, he estado alimentando datos de mql a aplicaciones C++/C# de terceros, sin ningún problema.

 
Vladimir Simakov:

Investiga en el propio dll, probablemente haya algo ahí. Últimamente, he estado alimentando datos de mql a aplicaciones C++/C# de terceros, sin ningún problema.

El dll es simple, no es necesario para la claridad, la idea en sí se muestra.

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

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

La salida de los datos del resultado a la consola, todas las líneas de la consola son claras, sin espacios y sin fallos.
Paso el resultado a mql a través de wcscpy(out, data), pero ahora tengo problemas.
Pero si paso una cadena de comprobación escrita a mano.

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

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

Por alguna razón no tengo problemas.

Hm, ¿el tipo string en mql considera terminal null wchar_t *?

Archivos adjuntos:
 

Sugerencia para ampliar un poco la posibilidad del evento OnTimer()

En este momento el evento OnTimer() comienza a producirse cuando la periodicidad de la llamada se establece con la función EventSetTimer().

Resulta que el siguiente Asesor Experto:

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);
}
//+------------------------------------------------------------------+

Las salidas son aproximadamente las siguientes:

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

Sin embargo, a menudo basta con comprobar la aparición de la señal tras la aparición de otra barra.

Por ejemplo, resulta que por ejemplo para PERIOD_M15, la barra aparece a las 00:15:00, pero la comprobación por parte del Asesor Experto sólo puede comprobarla a las 00:29:59.

Así, para obtener resultados más o menos estables e iguales, independientemente de la hora de inicio del Asesor Experto,

tendrá que establecer un temporizador para un intervalo de tiempo más corto o utilizar adicionalmente OnTick().

Como han demostrado los experimentos, reduce drásticamente la velocidad de las pruebas en el probador de estrategias.

Sugerencia:

Añadir una función que permita establecer el tiempo inicial a partir del cual se cuenta el evento OnTimer.

Por ejemplo, alguna función EventSetTimerFrom(const datetime SinceDT) que permita establecer la llamada al temporizador unos segundos después de una nueva barra.

 
Roman:

El dll es sencillo, se ha eliminado lo que sobra para mayor claridad, la idea se muestra.

Pego el resultado en la consola, todas las líneas están bien, sin huecos, sin fallos.
Paso el resultado a mql a través de wcscpy(out, data), pero ahora tengo problemas.
Si paso una cadena de comprobación escrita por mí mismo.

Por alguna razón no tengo problemas.

Hm, ¿el tipo string en mql considera terminal null wchar_t *?

Pero esta función funciona.

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

Pero no está del todo bien, parece que hay un carácter malo al final de la cadena, aparece un corchete extra } y luego desaparece.
wcslen(datos)+1
wcslen(datos)+2
no ayudó,
y es analizado sin errores, sin fugas.

ni idea de cuál es la longitud o el tamaño de un carácter en la cadena de aspecto mql
ciertamente hay un error en el tipo de cadena.

Y en un artículo de hace tiempo, en el apartado 3.3 Pasar y modificar cadenas, el ejemplo probablemente cometía un error.

_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 *)
  }

Tal vez en alguna parte del código de la terminal, la conversión de cadenas mql funciona de la misma manera, sin un puntero.

 
Maksim Emeliashin:

establece el tiempo inicial a partir del cual se realiza la cuenta atrás del evento OnTimer.

Puede hacerlo usted mismo mediante la llamada repetida de EventSetTimer. Tenga en cuenta que en la cuenta (no en el probador) el temporizador flota y necesita un ajuste constante.

 
fxsaber:

Puede hacerlo usted mismo mediante una llamada repetida a EventSetTimer. Tenga en cuenta que en la cuenta (no en el probador) el temporizador flota y necesita un ajuste constante.

Gracias, ¡cosa útil!

Muy extraño, por supuesto, que un punto tan simple no se tenga en cuenta en el terminal "fuera de la caja".

 
Roman:

Pero esta función funciona.

Pero parece ser un poco incómodo, un paréntesis extra } aparece o desaparece al final de la cadena.
wcslen(datos)+1
wcslen(datos)+2
no ayudó,
y es analizado sin errores, sin fugas.

ni idea de cuál es la longitud o el tamaño de un carácter en la cadena de aspecto mql
ciertamente hay un error en el tipo de cadena.

Y en un artículo de hace tiempo, en el apartado 3.3 Pasar y modificar cadenas, el ejemplo probablemente cometía un error.

Tal vez en alguna parte del código de la terminal, la conversión de la cadena mql funciona de la misma manera, sin el puntero.

getData() dig. Tengo la sensación de que hay un problema en alguna parte.
 
Roman:

El dll es sencillo, se ha eliminado para mayor claridad y se muestra la idea

Tus ejemplos son graciosos, has quitado todo, has dejado UB (modificación de literales de cadena), y todo el mundo tiene que telepatear. Si esperas recibir un consejo inteligente, da un código mínimo que funcione (en dos lados), de lo contrario es una basura.