Erreurs, bugs, questions - page 2590

 
Ilyas:


@Ilyas

Depuis la dll, le pointeur vers la chaîne de caractères const wchar_t* copie une chaîne de caractères paire, avec les paramètres suivants

memcpy( out, data, wcslen(data) * sizeof(int) );
wcsncpy( out, data, wcslen(data) * 2 );

Avec ces paramètres, bien sûr, il y a des fuites.

2019.10.11 04:32:37.857 ExampleDll      M 739
2019.10.11 04:32:37.857 ExampleDll       660
2019.10.11 04:32:37.857 ExampleDll       701

Mais la chaîne de caractères s'avère être égale, pas un seul caractère supplémentaire ne s'y glisse.
Et après avoir terminé le programme, le journal du conseiller-expert affiche un message

2019.10.11 03:44:39.202 ExampleDll      1 leaked strings left


Et il existe un tel test.

void OnStart()
{  
   Print("sizeof(char)   = " + (string)sizeof(char));
   Print("sizeof(' ')    = " + (string)sizeof(' '));
   Print("sizeof(\"\")   = " + (string)sizeof(""));
   Print("sizeof(string) = " + (string)sizeof(string));
}

Il présente les éléments suivants

2019.10.11 03:48:01.366 TestScript (EURUSD,H1)  sizeof(char)   = 1
2019.10.11 03:48:01.366 TestScript (EURUSD,H1)  sizeof(' ')    = 2
2019.10.11 03:48:01.366 TestScript (EURUSD,H1)  sizeof("")     = 12
2019.10.11 03:48:01.366 TestScript (EURUSD,H1)  sizeof(string) = 12

Le caractère ' ' renvoie deux octets au lieu d'un. Probablement parce que c'est en Unicode.
Et la chaîne de caractères renvoie douze octets chacun au lieu de deux octets par rapport à wchar_t.

Comme moyen possible, peut-être que l'alignement de type supérieur déforme la taille de la corde quelque part ?


 
Roman:

@Ilyas

A partir de la dll, le pointeur vers la chaîne const wchar_t* copie une chaîne paire, avec ces paramètres

Avec ces paramètres, bien sûr, il y a des fuites.

Mais la chaîne de caractères est égale, pas un seul caractère supplémentaire ne s'y glisse.
Et après avoir terminé le programme, le journal du conseiller-expert affiche un message


Et il existe un tel test.

Il présente les éléments suivants

Le caractère ' ' renvoie deux octets au lieu d'un. Probablement parce que c'est en Unicode.
Et la chaîne de caractères renvoie douze octets chacun au lieu de deux octets par rapport à wchar_t.

Comme moyen possible, peut-être que l'alignement de type supérieur déforme la taille de la corde quelque part ?


string est un objet qui possède autre chose qu'un pointeur vers une chaîne.
 
Bonjour à tous ! Il semble que la fonction ResourceReadImage() ne fonctionne pas correctement lors de la récupération de données à partir de fichiers BMP ! J'ai fait un script pour dessiner une image comme fond sur la toile. Si nous extrayons une image d'un fichier situé sur un disque dur et la remplissons simplement sur le canevas, tout fonctionne bien, mais si nous extrayons des pixels d'une ressource BMP qui se trouve dans le fichier ex5 lui-même en utilisant la fonction ResourceReadImage(), l'image résultante ressemblera à une tranche minuscule et fortement agrandie de l'image source. Quelle en est la raison ?
//+------------------------------------------------------------------+
//|                                             BMP_Background_X.mqh |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009-2017, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
//#property description "Создание фоновой подложки с картиной из BMP файла"
//+------------------------------------------------------------------+
#include <Canvas\Canvas.mqh>
#include <\Canvas\Charts\ChartCanvas.mqh>
#include <Arrays\ArrayObj.mqh>
#resource "\\Files\\bmp_resource_002.bmp" // bmp_resource_002.bmp находится в каталог_данных_терминала\MQL5\Files\ 

//+------------------------------------------------------------------+
//| inputs                                                           |
//+------------------------------------------------------------------+
input int      X=10; //координата X
input int      Y=60; //координата Y
input color    Color=clrMagenta; //цвет заливки
input uchar    BackgroundTransparentLevel=150;  //прозрачность ценового графика и его фона
//input string   FileName="bmp_resource_001.bmp"; //имя BMP рисунока из папки \MQL5\File
input string   ResName="CanvasBackground"; //имя создаваемого графического ресурса
CChartCanvas canvas;  //создание канвы
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
int OnStart(void)
  {  
//--- Создадим канву
   int width=50;
   int height=50;
//--- COLOR_FORMAT_ARGB_RAW - Компоненты цвета не обрабатываются терминалом (должны быть корректно заданы пользователем)
//--- COLOR_FORMAT_ARGB_NORMALIZE - Компоненты цвета обрабатываются терминалом
//--- COLOR_FORMAT_XRGB_NOALPHA - Компонента альфа-канала (прозрачность) игнорируется
   if(!canvas.CreateBitmapLabel(ResName,X,Y,width,height,COLOR_FORMAT_ARGB_NORMALIZE))
     {
      Print("Error creating canvas: ",GetLastError());
      return(false);
     }
     
//--- Грузим фон на канву из файла на жёстком диске (делаем фоновый рисунок из BMP файла)
   canvas.LoadFromFile("bmp_resource_002.bmp"); //грузим рисунок из папки \MQL5\Files
   canvas.Update(); //фон нарисован 
   Sleep(10000); //пауза десять секунд   

//--- стираем полученный результат и обновляем график
   canvas.Erase(ColorToARGB(clrBlack,0));
   canvas.Update();
   Sleep(3000); //пауза три секунды
   
//--- Грузим фон на канву из данного ex5 файла скрипта (делаем фоновый рисунок из ресурса)
   string path="::Files\\bmp_resource_002.bmp";
   uint bmp_data[]; //массив для получения пикселов
   ResourceReadImage(path,bmp_data,width,height); // получаем массив пикселей 
   Print("Итоговый размер массива с пикселами: "+string(ArraySize(bmp_data)));
   Print("Разрешение полученного изображения: "+string(width)+" X "+string(height));
//--- меняем размер канвы 
   canvas.Resize(width,height);

//--- заливаем фон из массива на канву
   for(int x1=0; x1<width && !IsStopped(); x1++)
      for(int y1=0; y1<height && !IsStopped(); y1++)
        {
         canvas.PixelSet(x1,y1,bmp_data[x1+y1]);
        }
   canvas.Update();
   Sleep(5000); //пауза пять секунд
//--- стираем полученный результат и обновляем график
   canvas.Erase(ColorToARGB(clrBlack,0));
   canvas.Update();
//--- завершение работы кода по созданию подложки
   ObjectDelete(0,ResName);
   ResourceFree(path); 
   canvas.Destroy();
//----
   ChartRedraw(0);
   return(0);
  }
//+------------------------------------------------------------------+
Dossiers :
 
Roman:

@Ilyas

Dans le DLL, le pointeur const wchar_t* string copie une chaîne de caractères simple, avec les paramètres suivants

Avec ces paramètres, bien sûr, il y a des fuites.

Mais la chaîne s'avère être une chaîne paire, sans aucun caractère supplémentaire manquant.
Et après avoir terminé le programme, le journal du conseiller-expert affiche un message


Et il existe un tel test.

Il présente les éléments suivants

Le caractère ' ' renvoie deux octets au lieu d'un. Probablement parce que c'est en Unicode.
Et la chaîne de caractères renvoie douze octets chacun au lieu de deux octets par rapport à wchar_t.

Comme moyen possible, peut-être que l'alignement de type supérieur déforme la taille de la corde quelque part ?


1. dans MQL seulement Unicode, c'est pourquoi la taille du caractère est de 2 octets

2. La chaîne est une structure (4 octets de tampon et 8 octets de pointeur).


La copie de la chaîne doit être

wcscpy(out,data);

Si cela ne fonctionne pas, l'erreur doit être trouvée ailleurs.

 
Nikolay Kositsin:
Bonjour à tous ! Il semble que la fonction ResourceReadImage() ne fonctionne pas correctement lors de la récupération de données à partir de fichiers BMP ! J'ai fait un script pour dessiner une image comme fond sur la toile. Si nous prenons les pixels d'une image à partir d'un fichier situé sur le disque dur et que nous la remplissons simplement sur le canevas, tout fonctionne bien, mais si nous prenons les pixels d'une image à partir d'une ressource BMP qui se trouve dans le fichier ex5 lui-même en utilisant la fonction ResourceReadImage(), l'image de fond résultante ressemblera à une tranche minuscule et fortement agrandie de l'image source. Quelle en est la raison ?

Le cycle de point de copie est erroné, remplacez-le par

//--- заливаем фон из массива на канву
   for(int y1=0; y1<height && !IsStopped(); y1++)
      for(int x1=0; x1<width; x1++)
        {
         canvas.PixelSet(x1,y1,bmp_data[y1*width+x1]);
        }
 

Et cette question - comment obtenir une liste de variables d'entrée, la même que celle de la fonctionFrameInputs() , mais en un seul passage, sans optimisation ?

Oui, une telle question a été soulevée récemment, je l'ai manquée d'une manière ou d'une autre, et maintenant j'ai moi-même une tâche de ce type (je veux créer des fichiers set automatiquement).

Dans quelle direction creuser ? Et si quelqu'un se souvient de cette discussion, où se trouve-t-elle (je ne la trouve pas) ?

Bien sûr, dans chaque conseiller expert, je pourrais écrire une fonction qui créerait une telle liste, mais il serait préférable d'avoir une fonction de bibliothèque universelle.
 
Georgiy Merts:

Vous pourriez, bien sûr, écrire une fonction unique dans chaque EA qui créerait une telle liste, mais une fonction de bibliothèque universelle serait préférable.

Jetez un coup d'œil ici.

 
fxsaber:

Jetez un coup d'œil ici.

C'est ça, c'est ça !

Merci beaucoup.

 
Ilyas:

1. dans MQL seulement Unicode, c'est pourquoi la taille du caractère est de 2 octets

2. La chaîne est une structure (4 octets de tampon et 8 octets de pointeur).


La copie de la chaîne doit être

Si cela ne fonctionne pas, l'erreur doit être trouvée ailleurs.

Et que se passe-t-il si la taille de la chaîne à copier est supérieure ou inférieure à la taille du tampon alloué ?

 
Koldun Zloy:

Que se passe-t-il si la chaîne copiée est plus grande ou plus petite que la taille du tampon alloué ?

Si c'est plus petit, c'est OK, en général le tampon de la chaîne est toujours légèrement plus grand que la chaîne elle-même (mais ce n'est pas un fait !).

Mais si vous écrivez plus que cela, il est presque garanti que le terminal se plantera.
Et le crash ne se produira probablement pas immédiatement, mais seulement lors de la prochaine utilisation de la mémoire dynamique (réaffectation des tableaux ou des tampons de chaînes de caractères) ou lors de l'arrêt, lorsque la mémoire du programme MQL utilisée est rendue au système.

Raison: