Dans MQL5, il y a toujours de la place pour un exploit ! ;) - page 3

 
mql5:
En bref.
Les fonctions des bibliothèques système pour les processus x86 (32 bits) ont un emballage spécial par lequel elles sont transmises à x64, exécutées et renvoyées à x86.

Windows 64 bits possède un dossier appelé SysWOW64. Ce dossier est destiné aux applications 32 bits lancées dans le système d'exploitation 64 bits, tandis que les bibliothèques et pilotes 64 bits ordinaires sont stockés dans le dossier System32. Si le programme est lancé en tant que programme 32 bits, les références au dossier System32 sont redirigées vers SysWOW64.

Pour être bref, le problème des 32/64 bits est devenu aigu dans MT5.

Il s'agit d'une question très importante et il est grand temps qu'elle soit abordée.

ou ajouter un dossier libraries64 pour que le terminal sache où trouver les bibliothèques
ou ajouter un moyen de disperser les DLLs dans les dossiers system32/SysWow64
ou utiliser #ifdef

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

ZS.
application à SD #381730

 
MetaDriver:

Tableau de dimension quelconque (pour plus de clarté, limitons-le à ^16).

La dimensionnalité est définie à la création par le nombre de paramètres, comme pour les tableaux normaux.

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

Les indexeurs doivent fonctionner pour toutes les dimensions ( A[i][j][k][n][m]....)

Eh bien, puisque la communauté est silencieuse, je vais continuer...

Un aperçu d'une classe de tableaux (doubles) à N dimensions et un test pour la tester.

La dimensionnalité est décrite par le tableau (int) dans le constructeur.

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

La deuxième variante est un tableau à N dimensions (double). La structure du tableau est également spécifiée dans le constructeur par un autre tableau (int).

Cette variante est un peu plus rapide que la précédente. Et dans cette variante, il est plus facile de créer des opérations avec des sous-réseaux.

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 deuxième variante est un tableau à N dimensions (double). La structure du tableau est également spécifiée dans le constructeur par un autre tableau (int).

Cette variante est un peu plus rapide que la précédente. Et dans cette variante, il est plus facile de créer des opérations avec des sous-réseaux.

Yurich, vous êtes un gars cool. J'ai été distrait du forum pendant quelques jours, et vous avez déjà fait quelques variantes.

Première impression - la première variante est truffée de problèmes lors d'appels incorrects avec un nombre réduit d'index : par exemple, double x=A[i][j][k] ; un "appel tridimensionnel" pour un tableau à quatre dimensions renverra le double comme si de rien n'était, mais à partir de toute autre position du tableau que l'utilisateur souhaitait.Et il n'est pas évident de tracer et de gérer de telles erreurs. Mais l'avantage indiscutable de la première implémentation est l'économie de mémoire. La deuxième façon est beaucoup plus gaspilleuse. Mais, comme vous l'avez correctement remarqué, vous pouvez essayer de passer par des sous-rays dans celle-ci et toutes les difficultés sont tout à fait gérables dans ce cas.

J'ai quelques idées, mais je n'aurai pas de temps libre avant la veille, si tant est que j'y arrive. Mais on y arrivera, je te le promets. :)

--

Idée de base : utiliser une classe supplémentaire, quelque chose comme "left indexes controller", et l'index le plus à droite à traiter par la classe principale (si cela fonctionne. Sinon, alors une classe supplémentaire pour l'index de droite). Ce faisant, le tableau de base double (unidimensionnel et unique) doit devenir un membre de la classe principale CNArray. Quelque chose comme ça.

 
MetaDriver

Tx. Première impression - la première variante est truffée de problèmes lors d'appels incorrects avec un nombre d'index inférieur : par exemple, double x=A[i][j][k] ; un "appel tridimensionnel" pour un tableau à quatre dimensions retournera le double comme si rien ne s'était passé, mais en même temps à partir de la position du tableau que l'utilisateur voulait. De plus, on ne voit pas comment repérer et gérer de telles erreurs.

J'ai joué avec la première méthode de Yurich, et il semble qu'il soit possible de contrôler le rang du tableau de cette façon :

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

Tâche :

- Pour passer un tableau de nombres de l'Expert Advisor à l'indicateur.


Exigences.

Ne pas utiliser
- des événements graphiques,
- des fichiers,
- les variables globales (également appelées fichiers),
- dll

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

Tâche :

- Pour passer un tableau de nombres de l'Expert Advisor à l'indicateur.


Exigences.

- N'utilisez pas les événements graphiques, les fichiers, les dll pour le transfert de données.

Lesvariables globales du terminal fonctionnent-elles ?
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Основы языка / Переменные / Глобальные переменные - Документация по MQL5
 
Ensuite, les canaux nommés restent.
 
sandex:
Ensuite, les canaux nommés restent.
qui est le serveur ?
 
sergeev:

Tâche :

- Pour passer un tableau de nombres de l'Expert Advisor à l'indicateur.


Conditions.

Ne pas utiliser
- des événements graphiques,
- des fichiers,
- les variables globales (alias fichiers),
- dll

Il n'y a personne pour le faire :)

Je propose alors une autre variante - utiliser le sous-graphe et les fonctionsChartSetString()etChartGetString().