¡En MQL5 siempre hay espacio para un exploit ! ;) - página 3

 
mql5:
Brevemente.
Las funciones de las bibliotecas del sistema para procesos x86 (32 bits) tienen una envoltura especial a través de la cual se pasan a x64, se ejecutan y se devuelven a x86.

Windows de 64 bits tiene una carpeta llamada SysWOW64. Esta carpeta está destinada a las aplicaciones de 32 bits lanzadas en el sistema operativo de 64 bits, mientras que las bibliotecas y los controladores normales de 64 bits se almacenan en la carpeta System32. Si el programa se lanza como uno de 32 bits, las referencias a la carpeta System32 se redirigen a SysWOW64.

Para ser breve, el tema de los 32/64 bits se ha agudizado en MT5.

este es un tema muy importante y ya es hora de que se aborde.

o añadir una carpeta libraries64 para que el terminal sepa de dónde obtener las bibliotecas
o añadir alguna forma de dispersar las DLL en las carpetas system32/SysWow64
o utilizar #ifdef

https://www.mql5.com/ru/forum/6729#comment_199764

ZS.
solicitud a SD #381730

 
MetaDriver:

Array de cualquier dimensionalidad (para mayor claridad, digamos que se limita a ^16).

La dimensionalidad se establece en el momento de la creación por el número de parámetros, como en el caso de las matrices normales.

XXArray  xx2(5,7),  xx5(12,12,16,16,8);

Los indexadores deben funcionar para todas las dimensiones ( A[i][j][k][n][m]....)

Bueno, ya que la comunidad está en silencio, continuaré...

Un esquema de una clase de array N-dimensional (doble) y un test para probarlo.

La dimensionalidad se describe mediante un array (int) en el constructor.

//+------------------------------------------------------------------+
class CNXdouble
{
        double                 value[];
        int                    size[];
        int                    index;
        int                    ivalue;
public:
                               CNXdouble(const int &n[]);
                              ~CNXdouble()   { ArrayFree(value); ArrayFree(size);}
        double      operator[]   (long x_);
        CNXdouble  *operator[]  (int x_)      { ivalue+=x_*size[index++]; return(GetPointer(this));}
        void         operator=    (double d)    { value[ivalue]=d; index=0; ivalue=0;}
};
//+------------------------------------------------------------------+
CNXdouble::CNXdouble(const int &n[])
{
        int m=1, k=ArraySize(n);
        ArrayResize(size,k);
        size[k-1]=1;
        for(int i=k-2; i>=0; i--) size[i]=n[i+1]*size[i+1];
        for(int i=0; i<k; i++) m*=n[i];
        ArrayResize(value,m);
        index=0;
        ivalue=0;
}
//+------------------------------------------------------------------+
double CNXdouble::operator[] (long x_) 
{
        index=0;
        int i=ivalue;
        ivalue=0;
        return(value[i+(int)x_]);
}
//+------------------------------------------------------------------+
void OnStart()
{
   int n[]={2,3,4,2};      //описание 4-х мерного массива
   int a1=n[0], a2=n[1], a3=n[2], a4=n[3];
   CNXdouble d2(n);
   //запись в массив
   int c=0;
   for(int i=0; i<a1; i++)
       for(int j=0; j<a2; j++) 
           for(int x=0; x<a3; x++) 
               for(int y=0; y<a4; y++)
                   d2[i][j][x][y]=(double)c++;
   //чтение из массива
   string s="";
   for(int i=0; i<a1; i++)
       for(int j=0; j<a2; j++) 
           for(int x=0; x<a3; x++)
               for(long y=0; y<a4; y++)
                   s+=(string)d2[i][j][x][y]+" ";
   Print(s);
}
//+------------------------------------------------------------------+
Archivos adjuntos:
 

La segunda variante es una matriz N-dimensional (doble). La estructura del array también se especifica en el constructor mediante otro array (int).

Esta variante es un poco más rápida que la anterior. Y en esta variante es más fácil crear operaciones con subarreglos.

class CNArray
{
        CNArray                    *array[];
        double                      value[];
        bool                        last;
        int                         ivalue;
public:
                                   CNArray(const int &n[]);
                                  ~CNArray();
        double      operator[]      (long x);
        CNArray*   operator[]      (int x);
        void        operator=       (double d) { if(last)value[ivalue]=d;}
};
//+------------------------------------------------------------------+
CNArray::CNArray(const int &n[])
{
        int k=ArraySize(n);
        if(k>1)
        {
                ArrayResize(array,n[0]);
                int n1[];
                ArrayResize(n1,k-1);
                for(int i=0; i<k-1; i++) n1[i]=n[i+1];
                for(int i=0; i<n[0]; i++) array[i]=new CNArray(n1);
                ArrayFree(n1);
                last=false;
        }else if(k==1)
        {
                ArrayResize(value,n[0]);
                last=true;
        }
}
//+------------------------------------------------------------------+
CNArray::~CNArray()
{ 
        if(!last)
        {
                int n=ArraySize(array);
                for(int i=0; i<n; i++) delete array[i];
                ArrayFree(array);
        }else ArrayFree(value);
}
//+------------------------------------------------------------------+
double CNArray::operator[](long x) 
{
        if(last) return(value[(int)x]); else return(0);
}
//+------------------------------------------------------------------+
CNArray* CNArray::operator[](int x)
{ 
        if(last)
        {
                ivalue=x; 
                return(GetPointer(this));
        }else return(array[x]);
}
 
Yurich:

La segunda variante es una matriz N-dimensional (doble). La estructura del array también se especifica en el constructor mediante otro array (int).

Esta variante es un poco más rápida que la anterior. Y en esta variante, es más fácil crear operaciones con subarreglos.

Yurich, eres un tío genial, he estado distraído del foro un par de días y ya has hecho un par de variantes.

Primera impresión - la primera variante está plagada de fallos en la llamada incorrecta con menos número de índices: por ejemplo double x=A[i][j][k]; la "llamada tridimensional" para un array de cuatro dimensiones devolverá double como si no fuera gran cosa, pero desde cualquier otra posición del array que el usuario quisiera.Pero la ventaja indiscutible de la primera implementación es la economía de memoria. La segunda forma es mucho más dispendiosa. Pero, como has notado correctamente, puedes intentar pasar a subarreglos en ella y todas las dificultades son bastante manejables en este caso.

Tengo algunas ideas, pero no tendré tiempo libre hasta la noche anterior, si es que llego. Pero lo conseguiremos, lo prometo. :)

--

Idea básica: utilizar una clase más, algo así como "controlador de índices de la izquierda", y el índice de la derecha para procesar por la clase principal (si va a funcionar. Si no, entonces una clase más para el índice de la derecha). Al hacerlo, el array base double (unidimensional y único) debe hacerse miembro de la clase principal CNArray. Algo así.

 
MetaDriver

Tx. Primera impresión - la primera variante está plagada de fallos en la llamada incorrecta con menos número de índices: es decir, por ejemplo, double x=A[i][j][k]; la "llamada tridimensional" para un array de cuatro dimensiones devolverá double como si no hubiera pasado nada, pero en la posición del array que el usuario quería. Y no es visible qué manera de rastrear y manejar este tipo de errores.

He estado jugando con el primer método de Yurich, y parece que es posible controlar el rango del array de esta manera:

class DinArr_Double{
        double                 value[];
        int                    size[];
        int                    index;
        int                    ivalue;
        int                    range;
        bool                   checkerror;
public:
                               DinArr_Double(const int &n[]);
                              ~DinArr_Double()   { ArrayFree(value); ArrayFree(size);}
        double          operator[](long x_);
        DinArr_Double*  operator[](int x_);
        void            operator= (double d)    { value[ivalue]=d; index=0; ivalue=0;}
};
//+------------------------------------------------------------------+
DinArr_Double::DinArr_Double(const int &n[]){
        int m=1, k=ArraySize(n);
        range = ArraySize(n);
        ArrayResize(size,k);
        size[k-1]=1;
        for(int i=k-2; i>=0; i--) size[i]=n[i+1]*size[i+1];
        for(int i=0; i<k; i++) m*=n[i];
        ArrayResize(value,m);
        index=0;
        ivalue=0;
        checkerror = false;
}
//+------------------------------------------------------------------+
double DinArr_Double::operator[](long x_){
        index=0;
        int i=ivalue;
        ivalue=0;
        return(value[i+(int)x_]);
}
//+------------------------------------------------------------------+
DinArr_Double*  DinArr_Double::operator[](int x_){
      ivalue+=x_*size[index++];
      if(index!=range)checkerror = true; else checkerror = false;
      return(GetPointer(this)); } //+------------------------------------------------------------------+ void OnStart(){    int n[]={2,3,4,2};      //описание 4-х мерного массива    int a1=n[0], a2=n[1], a3=n[2], a4=n[3];    DinArr_Double d2(n);    //запись в массив    int c=0;    for(int i=0; i<a1; i++)        for(int j=0; j<a2; j++)            for(int x=0; x<a3; x++)                for(int y=0; y<a4; y++)                    d2[i][j][x][y]=(double)c++;    //чтение из массива    string s="";    for(int i=0; i<a1; i++)        for(int j=0; j<a2; j++)            for(int x=0; x<a3; x++)                for(long y=0; y<a4; y++)                    s+=(string)d2[i][j][x][y]+" ";    Print(s); } //+------------------------------------------------------------------+
 

Tarea:

- Para pasar una matriz de números del Asesor Experto al indicador.


Requisitos.

No utilice
- eventos de la carta,
- archivos,
- variables globales (también conocidas como archivos),
- dll

Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Основы языка / Переменные / Глобальные переменные - Документация по MQL5
 
sergeev:

Tarea:

- Para pasar una matriz de números del Asesor Experto al indicador.


Requisitos.

- No utilice eventos de gráficos, archivos, dll para la transferencia de datos

¿Funcionarán lasvariables globales del terminal?
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Основы языка / Переменные / Глобальные переменные - Документация по MQL5
 
Entonces, los canales con nombre permanecen.
 
sandex:
Entonces, los canales con nombre permanecen.
¿quién es el servidor?
 
sergeev:

Tarea:

- Para pasar una matriz de números del Asesor Experto al indicador.


Condiciones.

No utilice
- eventos de la carta,
- archivos,
- variables globales (también conocidas como archivos),
- dll

No hay nadie que lo haga :)

Entonces propongo otra variante - utilizar el subgráfico y las funcionesChartSetString()yChartGetString().