Jump to content
Sign in to follow this  
Л_Е_О

MMF - обмен данными между терминалами, советниками через виртуальные файлы ?!

Recommended Posts

Л_Е_О

Shared Memory

 

MMF - Mamory Mapped Files

 

Обмен данными между скриптами, советниками, роботами и прочими программами в среде Windows.

Кто-нибудь под MT4 писал, использовал ?!

Через файлы обмениваться крайне медленно, особенно если данных много.

Подскажите как сделать - или дайте ссылку, плз. ?!


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Л_Е_О

 

Спасибо.

 

Сложноватый, на первый взгляд, метод.

Но, я как раз люблю сложности ...

 

Изучу, поделюсь результатами !


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Л_Е_О

Предварительные раскопки начинающего программера привели к следующему:

 

 

Для работы с виртуальными файлами в оперативной памяти (в дальнейшем по тексту: мемфайлы) необходимо выполнить несколько этапов:

 

  1. Создание мемфайла и назначение имени мемфайла, атрибутов и размера. Все эти задачи выполяет функция: CreateFileMapping.
  2. Захват области памяти для дальнейшего обмена данными. Эту задачу выполняет функция: MapViewOfFile.
  3. Один робот создаёт такие мемфайлы передаёт туда данные, а второй робот, программа, скрипт, DLL должен получить доступ к уже созданному мемфайлу. За открытие мемфайла отвечает следующая функция: OpenFileMapping.
  4. Освободить захваченную мемфайлом часть (кусок, область) памяти помогает функция: UnmapViewOfFile.
  5. Перед окончанием работы с мемфайлами необходимо выдать ещё одну коротенькую функцию: CloseHandle. Она освобождает назначенный указатель в памяти для работы с мемфайлом.

Вообщем-то для начала работы, ИМХО, я думаю, что функций вполне достаточно !

 

 

Осталось разобраться как с созданным мемфайлом осуществлять операции чтение/запись. Если кто подскажет раньше, чем я найду - буду рад.

 

ПС:

Кстати, совсем забыл сказать, что все эти функции "захвачены" DLL под названием: kernel32.dll.

 

Да и ещё: не люблю пользоваться чужими DLL без исходных текстов, т.к. какими бы они крутыми внешне не были, могут ВАС подвести в любую секунду. Либо пишите сами, либо знайте, что в этих DLL творится, либо автор DLL очень надёжный, проверенный временем и практикой использования его программ, человек.

Edited by Л_Е_О

Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Л_Е_О

Получилось же !

 

ВИДЕО-РОЛИК

 

Пояснения к видео-ролику:

1. верхний экран - работает скрипт и пишет в общий мемфайл;

2. нижний экран - скрипт читает из общего мемфайла.

 

Текст верхнего скрипта (пишущего):

 

 
#import "kernel32.dll"
     int CreateFileMappingA (int h, int ihv, int PRW, int LD, int WD, string Name);
     int CloseHandle (int hMapFile);
     int OpenFileMappingA (int h, int ihv, int PRW, string Name);
     int UnMapViewOfFile (int h);
#import
#import "mmf.dll"
     int GetArray(int hMapFile, int& St[]);
     int PutArray(int hMapFile, int& St[]);
#import
int   hMapFile, h;
int   St[32] = {0,4,2,1};
int   deinit() {
     CloseHandle (hMapFile);
     return(0);
}
int   start() {
     hMapFile = CreateFileMappingA (-1, NULL, 4, 0, 32, "MMFile");
     if (hMapFile == 0) return (-1);
     PutArray(hMapFile,St);
     CreateString (1,1,0,12,16);
     while (!IsStopped()) {
           St[0]++; 
           PutArray(hMapFile,St); 
           SPrint (1,1,StringConcatenate("Write: ",St[0]),72,"Digiface",Gray,0); 
           WindowRedraw();
           Sleep(500);
     }
     return(0);
}
void  CreateString (int i, int j, int pr, int x, int y) 
{      
     ObjectCreate   (StringConcatenate("Строка",i,j,pr), OBJ_LABEL,0,0,0);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_CORNER, pr);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_XDISTANCE,x*j);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_YDISTANCE,y*i);
     return(0);
}
///////////////////////////////////////////////////////////////////////////////////
//    SPrint (int i, int j, string Text, int Size, string Font, color Col, int pr) 
//    int i -        номер строки (1 - 50)
//    string Text -  текст строки
//    int Size -     размер шрифта (до 11)
//    string Font -  имя шрифта (Courier New)
//    color Col -    цвет шрифта
//    int pr -       привязка к углу (0-3)
///////////////////////////////////////////////////////////////////////////////////
void  SPrint (int i, int j, string Text, int Size, string Font, color Col, int pr) 
{
     ObjectSetText  (StringConcatenate("Строка",i,j,pr), Text, Size, Font, Col);
     return(0);
}

 

Текст нижнего скрипта (читающего):

 

 
//+------------------------------------------------------------------+
//|                                       Copyright © 2011, Iol, Leo |
//+------------------------------------------------------------------+
#import "kernel32.dll"
     int CreateFileMappingA (int h, int ihv, int PRW, int LD, int WD, string Name);
     int CloseHandle (int hMapFile);
     int OpenFileMappingA (int h, int ihv, string Name);
#import
#import "mmf.dll"
     int GetArray(int hMapFile, int& St[]);
     int PutArray(int hMapFile, int& St[]);
#import
int   hMapFile, h;
int   B[32] = {10,10,10,10};
int start() {
     hMapFile    = OpenFileMappingA (2, 0, "MMFile");
     if (hMapFile == NULL) {
           Print ("Could not open file mapping object\n");
           return (-1);
     }
     Print (hMapFile);
     CreateString (1,1,0,12,16);
     while (true) {
           GetArray(hMapFile,; 
           SPrint (1,1,StringConcatenate("Read:  ",B[0]),72,"Digiface",Gray,0); 
           WindowRedraw();
           Sleep(100);
     }
     CloseHandle (hMapFile);
     return (0);
}
void  CreateString (int i, int j, int pr, int x, int y) 
{      
     ObjectCreate   (StringConcatenate("Строка",i,j,pr), OBJ_LABEL,0,0,0);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_CORNER, pr);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_XDISTANCE,x*j);
     ObjectSet      (StringConcatenate("Строка",i,j,pr), OBJPROP_YDISTANCE,y*i);
     return(0);
}
///////////////////////////////////////////////////////////////////////////////////
//    SPrint (int i, int j, string Text, int Size, string Font, color Col, int pr) 
//    int i -        номер строки (1 - 50)
//    string Text -  текст строки
//    int Size -     размер шрифта (до 11)
//    string Font -  имя шрифта (Courier New)
//    color Col -    цвет шрифта
//    int pr -       привязка к углу (0-3)
///////////////////////////////////////////////////////////////////////////////////
void  SPrint (int i, int j, string Text, int Size, string Font, color Col, int pr) 
{
     ObjectSetText  (StringConcatenate("Строка",i,j,pr), Text, Size, Font, Col);
     return(0);
}

 

 

Текст программ на C++:

 

 
MT4_EXPFUNC int __stdcall GetArray(HANDLE ipar, int* buf) {
LPDWORD lp = (LPDWORD) MapViewOfFile (ipar, FILE_MAP_ALL_ACCESS, 0, 0, 32);
memmove(buf, lp, 32);
UnmapViewOfFile (lp);
return (1);
}
MT4_EXPFUNC int __stdcall PutArray(HANDLE ipar, int* buf) {
LPDWORD lp = (LPDWORD) MapViewOfFile (ipar, FILE_MAP_ALL_ACCESS, 0, 0, 32);
memmove(lp, buf, 32);
UnmapViewOfFile (lp);
return (1);
}

Если есть вопросы - пишите !

Edited by Л_Е_О

Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo

Здравствуйте ЛЕО , очень бы хотелось разобраться в вашей работе , пока не могу понять где взять mmf.dll , не уверен что эта библиотека есть у меня , подскажите где взять ?

... и почему-то скрипты не запускаються , может то что выходной ?

Share this post


Link to post
Share on other sites
Л_Е_О
Здравствуйте ЛЕО , очень бы хотелось разобраться в вашей работе , пока не могу понять где взять mmf.dll , не уверен что эта библиотека есть у меня , подскажите где взять ?

... и почему-то скрипты не запускаються , может то что выходной ?

 

Я привёл программу на языке С++. Делайте из неё mmf.dll и у Вас всё получится !

Там как раз все программки, которые и вызываются из mmf.dll

Либо, используйте готовую библиотеку, которую я прилепил к данному посту.

 

ПС:

Выходные тут ни при чём.

MMF.zip

Edited by Л_Е_О

Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo

Спасибо , я как раз догадался ))) ... щас занимаюсь поиском компилятора , потому что на С++ у меня ничего нет

Share this post


Link to post
Share on other sites
Л_Е_О
Спасибо , я как раз догадался ))) ... щас занимаюсь поиском компилятора , потому что на С++ у меня ничего нет

Можно уже не искать !

Я ж mmf.dll выложил в архиве: mmf.zip ?!

Предварительно положите библиотеку в каталог: d:\КаталогТерминала\experts\libraries\

 

ПС:

Если не секрет, то как Вы собираетесь использовать эту передачу данных ?

Точнее: для чего это Вам нужно ?!


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo

... вот спасибо

Share this post


Link to post
Share on other sites
Л_Е_О

ВИДЕО, как это всё будет выполняться ...

 

ПС:

Так с какой целью интересуетесь ? Секрет ?!

Video_2011-09-09_234245.zip


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo
Можно уже не искать !

Я ж mmf.dll выложил в архиве: mmf.zip ?!

Предварительно положите библиотеку в каталог: d:\КаталогТерминала\experts\libraries\

 

ПС:

Если не секрет, то как Вы собираетесь использовать эту передачу данных ?

Точнее: для чего это Вам нужно ?!

 

Я вобще-то не хотел говорить для чего именно мне это нужно , потому как это личное ))) ... но справедливости ради отвечу , но тока в личку )) ...

... а вот скрипты так и не запускаються , сделал вроде всё правильно , написал даже Print ("gggg") для отладки после start() , но он и его не пишет (((

Share this post


Link to post
Share on other sites
Aequo_animo

Поместил dll как надо , а оно вот такое выдаёт

post-75267-1404216669,6552_thumb.jpg

Share this post


Link to post
Share on other sites
Л_Е_О
Поместил dll как надо , а оно вот такое выдаёт

У меня всё загружается, у компаньонов тоже ! Специально их сегодня в выходные напряг - они проверили. Всё Ок! Ищите проблему у себя либо делайте DLL сами. Теперь у вас есть все исходники ...

 

Почитайте тут:

http://forum.mql4.com/ru/6940#31830

 

Можно самому сделать DLL.

Я из встроенного ExpertSample делал, текст которого выложил.

ExpertSample.zip

Edited by Л_Е_О

Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo

Пошёл по вашей ссылке и нашёл что-то страшное и ужасное , буду разбираться ...

post-75267-1404216670,269_thumb.jpg

Share this post


Link to post
Share on other sites
Aequo_animo

Ура , наконец-то заработало

Share this post


Link to post
Share on other sites
Л_Е_О
Ура , наконец-то заработало

И что же там такого страшного было ?


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo
И что же там такого страшного было ?

Для меня всё страшно , что не понятно , а вот это как раз не мой конек , но вроде разобралься . Не хватало одной dll к которой обращаеться mmf.dll , с инета установил , вот и заработало .

Share this post


Link to post
Share on other sites
Л_Е_О
Для меня всё страшно , что не понятно , а вот это как раз не мой конек , но вроде разобралься . Не хватало одной dll к которой обращаеться mmf.dll , с инета установил , вот и заработало .

 

Так этой dll в Windows не хватало ?!


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo
Так этой dll в Windows не хватало ?!

 

Да , получаеться так . Я иногда пользую 3G-инетом , поэтому обновление винды отключил .

Share this post


Link to post
Share on other sites
Л_Е_О

Спросил бы ! И тебе тут любой бы скинул её:

post-74106-1404216684,3805_thumb.png


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Л_Е_О

Кстати, просьба проверить всем, у кого-нибудь такой скрипт не работает ?!

Если не фунциклирует, значит у Вас тоже что-то с DLL ...

 

 
#import "kernel32.dll"
int WinExec(string lpCmdLine,int uCmdShow);
int start() {
     WinExec ("calc",1); return(0);
}


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
qqmber

LEO, а два разных терминала могут общаться с помощью виртуальных файлов?


Gone.

Share this post


Link to post
Share on other sites
Л_Е_О
LEO, а два разных терминала могут общаться с помощью виртуальных файлов?

Ну ты спросил ?


Великие умы обсуждают идеи. Средние умы обсуждают события. Мелкие умы обсуждают людей !

Элеанор Рузвельт

Share this post


Link to post
Share on other sites
Aequo_animo

Предлaгаю переработанный вариант по работе с виртуальными файлами без использования  описанной здесь  mmf.dll . Я могу ошибаться но помоему автором mmf.dll является Алексей Волчанский (у него канал на ютубе), и вроде он её создавал лишь для демонстрации метода . Этой  mmf.dll можно передать лишь массив и 4-ёх (или8-и) int элементов , что маловато .
    Я не программист , поэтому за корректность комментариев не отвечаю , напишу как понимаю . Сразу пример "передатчика" , который передаёт массив из 32 double элементов в другой терминал

 

"передатчик" :
 

#import "kernel32.dll"
      int CreateFileMappingA (int h, int ihv, int PRW, int LD, int WD, string Name);
      int CloseHandle (int hMapFile);
      int MapViewOfFile (int hMapFile , int ppp, int jjj , int bb , int ff);
      int UnmapViewOfFile (int hMap);
   
#import "msvcr100.dll"
      int memmove (int hMap,double& St[],int bb);         // знак "&" говорит что это указатель на массив 
#import
 
int   hMapFile;
double   St[32];
int   hMap;
//-------------------------------
int   deinit() {
CloseHandle (hMapFile);
          return(0);
      }
//-------------------------------
int   start() {
 
      hMapFile = CreateFileMappingA (-1, NULL, 4, 0, 256, "MMFile");    // 256 потому-что 32 элемента по 8 байт
                                                                        // каждый 
 
 while (!IsStopped()){
 
      St[31]=St[31]+2.5;
      Print("хэндл   ", hMapFile);
      if (hMapFile == 0) return (-1);
      hMap=MapViewOfFile(hMapFile,2,0,0,256);     
      memmove (hMap,St,256);                     //копируем наш массив в виртуальную память
      UnmapViewOfFile (hMap);                    //не забывайте эту функцию ,
                                                 // иначе оперативная память может кончиться
 
        Sleep(2000);
      }
}

 
 
А теперь "приёмник" :
 

#import "kernel32.dll"
     
      int CloseHandle (int hMapFile);
      int OpenFileMappingA (int h, int ihv, string Name);
      int MapViewOfFile (int hMapFile , int ppp, int jjj , int bb , int ff);
      int UnmapViewOfFile (int hMap);
            
#import "msvcr100.dll"
      int memmove (double& B[] ,int hMap,int bb);     
#import
 
int   hMapFile , hMap;
double B[32];
 
int start() {
      hMapFile    = OpenFileMappingA (2, 0, "MMFile");
      if (hMapFile == NULL) {
           Alert ("Не удалось открыть отображение в памяти ");
            return (-1); }
      Print ("идентификатор mmf файла  ",hMapFile);  
      while (!IsStopped())
       {
        hMap=MapViewOfFile(hMapFile,2,0,0,256);   // 2 - это права доступа при которых                                                                                                   //получилось
        memmove (B,hMap,256);
        UnmapViewOfFile (hMap);
              Print(" B[31]=",B[31]);             // печатаем только один элемент массива
                                                  //но передаём весь массив
        
              Sleep (1500);
        }
}
//-------------------------------
int   deinit() {
CloseHandle (hMapFile);
          return(0);
      }
 

В общем загружаете один советник в один терминал , другой в другой . Открываем вкладку "эксперты" в терминале и смотрим , что он там пишет . Метод позволяет обмениваться данными через оперативную память , не гоняя жесткий диск . 
   О функции memmove лучше почитать в яндексе или гугле , лучше я не объясню , это стандартная для С++ функция . Единственно  уточню , если массив будет слишком большой и операционка разместит его в памяти не подряд , а в разные области , передать его весь функцией memmove не получиться .

Edited by Aequo_animo
  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×