Советники: Мониторинг котировок (пример для маппинга) - страница 2

 
Работает!
 

Сам скрипт из примера работает нормально. Только сам пример очень сложен и из него я никак не пойму что я делаю не так когда хочу записать строку в виртуальный файл, а затем считать из него.

Вот мой код:

//+------------------------------------------------------------------+
//|                                                          Monitor |
//|                                 Copyright 2006-2012, FXmaster.de |
//|     programming & support - Alexey Sergeev (profy.mql@gmail.com) |
//+------------------------------------------------------------------+
#property copyright "Copyright 2006-2012, FXmaster.de"
#property link      "profy.mql@gmail.com"

#include <stderror.mqh>
#include <stdlib.mqh>

// импортируем 
#define ERROR_FILE_NOT_FOUND            2 

// Flag values
#define modeOpen                                                                0 // флаг открытия
#define modeCreate                                                      1 // флаг создания

#import "MemMap32.dll"
int MemOpen(string path, int size, int mode, int &err[]); // открываем/создаем файл в памяти, получаем хендл
void MemClose(int hmem); // закрываем файл в памяти
int MemGrows(int hmem, string path, int newsize, int &err[]); // увеличиваем размер файла в памяти
int MemWrite(int hmem, int &v[], int pos, int sz, int &err[]); // запись int(4) вектора v в память с указанной позиции pos, размером sz
int MemRead(int hmem, int &v[], int pos, int sz, int &err[]); // чтение вектора v с указанной позиции pos размером sz
int MemWriteStr(int hmem, string str, int pos, int sz, int &err[]); // запись строки
int MemReadStr(int hmem, string str, int pos, int &sz[], int &err[]); // чтение строки вектора 
#import

extern int MaxLate=5000; // число милисекунд задержки для фильтра старой котировки

// данные файла
#define HEAD            8 // размер в начале файла, для хранения специнформации
#define iSize           16 // размер вектора для записи (4*int(4))
#define sSize           34 // размер вектора для записи (30*char)
#define Size            50 // полный размер вектора для записи
#define kprice  0.000001 // множитель для перевода цены в целое число

int hmem, hmem_my, err[1], err_my[1], price[][4], start_adr=0; string term[]; // массивы обмена
string file,file_my; // имя файла в памяти

string sID;
string g_inf;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   file_my="Local\\Test";
   string str="Hello world!";
   
   hmem_my=MemOpen(file_my, 100, modeCreate, err_my); // создаём файл
        
	if(hmem_my>0)
        {
           Print("IM: успешно создали файл в памяти h=",hmem_my);   
           int w1=MemWriteStr(hmem_my, str, 0, StringLen(str), err);       
           Print("IM: w1=",w1);
           str="N/A";
           int len[1];
	   int r=MemReadStr(hmem_my, str, 0, len, err);
      	   Print("IM: str after reading = ",str);
      
      	   MemClose(hmem_my);
   	 }   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+

В логах терминала наблюдаем следующее:

2017.04.14 02:24:37.005 Mem_test EURUSD,M5: initialized
2017.04.14 02:24:37.005 Mem_test EURUSD,M5: IM: str after reading = N/A
2017.04.14 02:24:37.005 Mem_test EURUSD,M5: IM: w1=0
2017.04.14 02:24:37.005 Mem_test EURUSD,M5: IM: Успешно создали файл в памяти h=444
2017.04.14 02:24:34.568 Mem_test EURUSD,M5 inputs: MaxLate=5000; 
2017.04.14 02:24:34.568 Expert Mem_test EURUSD,M5: loaded successfully

Вопрос в том почему не происходит считывания записанного значения? То есть я ожидаю эту строку в следующем виде:

2017.04.14 02:24:37.005 Mem_test EURUSD,M5: IM: str after reading = Hello world!


 

Пользуйтесь вариантом без DLL

https://www.mql5.com/ru/code/818

File Mapping без DLL
File Mapping без DLL
  • голосов: 32
  • 2012.01.16
  • o_o
  • www.mql5.com
Класс MQL5, который работает напрямую с маппингом, без использования самописной DLL.
 

Фантастика! Вариант без DLL отлично работает и в МТ4, который мне и нужен.

Теперь остаётся только выяснить вопрос о том как удаляется файл, созданный в памяти.

Или же в случае простого закрытия файла он в памяти удаляется автоматически без дополнительных действий, как это требуется при работе с обычными файлами?

 
Иван:

Или же в случае простого закрытия файла он в памяти удаляется автоматически без дополнительных действий, как это требуется при работе с обычными файлами?

Удаляется в случае, если корректно завершилось все. А так сталкивался, что некорректное завершение не позволяет дальше без краша использовать ранее использованные Memory-файлы.
 
fxsaber:
Удаляется в случае, если корректно завершилось все. А так сталкивался, что некорректное завершение не позволяет дальше без краша использовать ранее использованные Memory-файлы.
А есть ли какие-то железобетонные схемы работы с такими вот виртуальными файлами в случае, если что-то пошло не так и нужно чтобы советник сам разобрался и предпринял необходимые действия для возобновления работы с виртуальными файлами, имеющими те же самые наименования?
 
Иван:
А есть ли какие-то железобетонные схемы работы с такими вот виртуальными файлами в случае, если что-то пошло не так и нужно чтобы советник сам разобрался и предпринял необходимые действия для возобновления работы с виртуальными файлами, имеющими те же самые наименования?
Не знаю. Мне было проще просто изменить имя файла лишь в одном месте кода.
 
Иван:

Теперь остаётся только выяснить вопрос о том как удаляется файл, созданный в памяти.

Или же в случае простого закрытия файла он в памяти удаляется автоматически без дополнительных действий, как это требуется при работе с обычными файлами?

обычные файлы ведь тоже не удаляются. А только первый символ имени заменяется на "?".

C файлами в памяти еще проще - память вообще не чистится, а просто закрывается хендл на неё.

Поэтому будете встречаться с ситуацией, когда при открытии файла в памяти с таким же именем у него будут в этой памяти какие то данные от прошлого раза.

И если вам так важно обнулять ячейки памяти - то делайте это принудительно перед закрытием хендла.

 
fxsaber:
Не знаю. Мне было проще просто изменить имя файла лишь в одном месте кода.
Пока не могу представить как это у Вас сделано. Если идёт обмен данными между двумя терминалами и файл обмена переклинило так, что он не может быть открыт, то нужно будет менять имя наверное в обоих терминалах? А как согласовать на какое новое имя его нужно будет поменять? Просто какой-нибудь счётчик ошибок синхронный вставлять в новое имя, или же открывать новую резервную линию связи для обмена именем нового файла между терминалами создавать?
 
Иван:
Пока не могу представить как это у Вас сделано. Если идёт обмен данными между двумя терминалами и файл обмена переклинило так, что он не может быть открыт, то нужно будет менять имя наверное в обоих терминалах? А как согласовать на какое новое имя его нужно будет поменять? Просто какой-нибудь счётчик ошибок синхронный вставлять в новое имя, или же открывать новую резервную линию связи для обмена именем нового файла между терминалами создавать?

Все терминалы(и MT5 и MT4) залинкованы на одну MQL-папку - никаких противоречий не возникает.

Название файла сидит только в одном месте - в mqh-файле, который подключается ко всем соответствующим советникам.

Соответственно, поправив это место в mqh, получаю работоспособными все обменные советники.

Причина обращения: