In MQL5 gibt es immer Raum für einen Exploit! ;) - Seite 3

 
mql5:
Kurz und bündig.
Funktionen der Systembibliotheken für x86 (32-Bit)-Prozesse haben einen speziellen Wrapper, durch den sie an x64 weitergegeben, ausgeführt und wieder an x86 zurückgegeben werden.

64-Bit-Windows hat einen Ordner namens SysWOW64. Dieser Ordner ist für 32-Bit-Anwendungen gedacht, die in einem 64-Bit-Betriebssystem gestartet werden, während reguläre 64-Bit-Bibliotheken und -Treiber im Ordner System32 gespeichert werden. Wenn das Programm als 32-Bit-Programm gestartet wird, werden Verweise auf den Ordner System32 auf SysWOW64 umgeleitet.

Um es kurz zu machen: Das Problem der 32/64 Bits ist im MT5 akut geworden.

Dies ist ein sehr wichtiges Thema , und es ist an der Zeit, dass es angegangen wird.

oder fügen Sie einen libraries64-Ordner hinzu, damit das Terminal weiß, woher es die Bibliotheken beziehen soll
oder fügen Sie eine Möglichkeit hinzu, DLLs in die Windows-Ordner System32/SysWow64
zu verteilen oder lassen Sie sie #ifdef

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

ZS.
Anwendung auf SD #381730

 
MetaDriver:

Array mit beliebiger Dimensionalität (der Klarheit halber beschränken wir es auf ^16).

Die Dimensionalität wird bei der Erstellung durch die Anzahl der Parameter festgelegt, wie bei normalen Arrays.

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

Indexer sollten für alle Dimensionen funktionieren ( A[i][j][k][n][m]....)

Nun, da die Gemeinschaft schweigt, werde ich fortfahren...

Eine Skizze einer N-dimensionalen (double) Array-Klasse und ein Test, um sie zu testen.

Die Dimensionalität wird durch (int) array im Konstruktor beschrieben.

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

Die zweite Variante ist ein N-dimensionales (doppeltes) Array. Die Struktur des Arrays wird ebenfalls im Konstruktor durch ein weiteres (int) Array angegeben.

Diese Variante ist ein wenig schneller als die vorherige. Und bei dieser Variante ist es einfacher, Operationen mit Subarrays zu erstellen.

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:

Die zweite Variante ist ein N-dimensionales (doppeltes) Array. Die Struktur des Arrays wird ebenfalls im Konstruktor durch ein weiteres (int) Array angegeben.

Diese Variante ist ein wenig schneller als die vorherige. Und bei dieser Variante ist es einfacher, Operationen mit Subarrays zu erstellen.

Yurich, du bist ein cooler Typ. Ich war ein paar Tage vom Forum abgelenkt, und du hast schon ein paar Varianten gemacht.

Erster Eindruck - die erste Variante ist voller Pannen bei falschen Aufrufen mit weniger Indizes: z.B. double x=A[i][j][k]; "dreidimensionaler Aufruf" für vierdimensionales Array gibt double als keine große Sache zurück, aber von jeder anderen Position des Arrays, die der Benutzer wollte.Und es ist nicht klar, wie man solche Fehler aufspüren und behandeln soll. Aber der unbestreitbare Vorteil der ersten Implementierung ist die Speicherersparnis. Der zweite Weg ist viel verschwenderischer. Aber, wie Sie richtig bemerkt haben, können Sie versuchen, darin zu Subarrays durchzukommen, und alle Schwierigkeiten sind in diesem Fall recht überschaubar.

Ich habe ein paar Ideen, aber ich werde erst am Abend vorher Zeit haben, wenn ich überhaupt dazu komme. Aber wir werden es schaffen, das verspreche ich. :)

--

Grundidee: Verwenden Sie eine weitere Klasse, so etwas wie "linke Indizes Controller", und die ganz rechts Index von Hauptklasse zu verarbeiten (wenn es funktioniert. Wenn nicht, dann eine weitere Klasse für den rechten Index). Dabei sollte das Basis-Array double (eindimensional und das einzige) zu einem Mitglied der Hauptklasse CNArray gemacht werden. Das geht so.

 
MetaDriver

Tx. Erster Eindruck - die erste Variante ist voller Pannen bei falschem Aufruf mit weniger Indizes: z.B. double x=A[i][j][k]; "dreidimensionaler Aufruf" für vierdimensionales Array gibt double zurück, als wäre nichts passiert, aber gleichzeitig von der Array-Position, die der Benutzer wollte. Außerdem ist nicht ersichtlich, wie man solche Fehler aufspüren und behandeln soll.

Ich habe mit Yurichs erster Methode herumgespielt, und es scheint möglich zu sein, den Array-Rang auf diese Weise zu steuern:

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

Aufgabe:

- Zur Übergabe eines Zahlenfeldes vom Expert Advisor an den Indikator.


Anforderungen.

Nicht verwenden
- Ereignisse aufzeichnen,
- Dateien,
- globale Variablen (auch als Dateien bezeichnet),
- DLL

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

Aufgabe:

- Zur Übergabe eines Zahlenfeldes vom Expert Advisor an den Indikator.


Anforderungen.

- Verwenden Sie keine Diagrammereignisse, Dateien, dll für die Datenübertragung

Werdenglobale Variablen des Terminals funktionieren?
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Основы языка / Переменные / Глобальные переменные - Документация по MQL5
 
Dann bleiben die genannten Kanäle übrig.
 
sandex:
Dann bleiben die genannten Kanäle übrig.
Wer ist der Server?
 
sergeev:

Aufgabe:

- Zur Übergabe eines Zahlenfeldes vom Expert Advisor an den Indikator.


Bedingungen.

Nicht verwenden
- Ereignisse aufzeichnen,
- Dateien,
- globale Variablen (auch Dateien genannt),
- DLL

Es gibt niemanden, der das macht :)

Dann schlage ich eine andere Variante vor - die Verwendung von Subcharts undChartSetString()- undChartGetString()-Funktionen.