File Mapping, как сделать правильно?

 

Имеем код на базе этого примера https://www.mql5.com/ru/code/10571

Нужно записать и считать массив, но не работает... Как исправить?

//--------------------------------------------------------------------
#property indicator_chart_window
//--------------------------------------------------------------------

#define modeOpen   0
#define modeCreate 1
#define HEAD 8 
#define SIZE 12 
#import "MemMap32.dll"
int MemOpen(string path, int size, int mode, int &err[]);
int MemWrite(int hmem, int &v[], int pos, int sz, int &err[]);
//MemWrite(hmem,data,0,SIZE,err);
int MemRead(int hmem, int &v[], int pos, int sz, int &err[]);
//MemRead(hmem,data,0,SIZE,err);
int MemGetSize(int hmem, int &err[]);
int MemSetSize(int hmem, int size, int &err[]);
void MemClose(int hmem);
#import
int err[1];
//--------------------------------------------------------------------
void mcreate(string mname, string gname, int& hmem){
   hmem=MemOpen(mname, HEAD+SIZE, modeCreate, err);
   if(hmem <= 0 || err[0] != 0) Alert("mcreate_err:mname= "+mname);
   else{ Alert("new "+gname+"= "+hmem); GlobalVariableSet(gname,hmem); }
}// mcreate("Local\\History","hmem",hmem);
//--------------------------------------------------------------------
void mclose(string gname, int& hmem){
   MemClose(hmem); GlobalVariableSet(gname,0); hmem=0;
}// mclose("hmem",hmem);

int hmem, data[5];
//--------------------------------------------------------------------
int init(){ Alert("finit");

   hmem = GlobalVariableGet("hmem");
   if(hmem <= 0) mcreate("Local\\History","hmem",hmem);
   Alert(hmem);
   Alert(MemGetSize(hmem,err));
   MemSetSize(hmem,HEAD+5*SIZE,err);
//   Alert(MemGetSize(hmem,err));

   // Test: Write & Read 
   data[0]=1234999999; data[1]=-5678; data[3]=23451444;
   MemWrite(hmem,data,HEAD,SIZE,err);
   data[0]=0; data[1]=0; data[3]=0;
   MemRead(hmem,data,HEAD,SIZE,err);
   Alert("data[1]= "+data[3]);
//   mclose(hmem);

}
//--------------------------------------------------------------------
int start(){
}
//--------------------------------------------------------------------
 

Для сторонников простых решений сделал бы так:

#include <SharedMemoryMT4.mqh> // Заголовочный файл библиотеки "SharedMemoryMT4.dll".
string sNameMemory = "MyMem";
int aiOutArray[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int aiIncArray[10] = {0};

MemoryWriteIntArray(0, "", -1, sNameMemory, 0, aiOutArray, ArraySize(aiOutArray), 0, ArraySize(aiOutArray));
MemoryReadIntArray(0, "", -1, sNameMemory, 0, aiIncArray, ArraySize(aiIncArray), 0, ArraySize(aiIncArray));

Так тоже можно (ошибки не будет):

#include <SharedMemoryMT4.mqh> // Заголовочный файл библиотеки "SharedMemoryMT4.dll".
string sNameMemory = "MyMem";
int aiOutArray[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int aiIncArray[10] = {0};

MemoryReadIntArray(0, "", -1, sNameMemory, 0, aiIncArray, ArraySize(aiIncArray), 0, ArraySize(aiIncArray));
MemoryWriteIntArray(0, "", -1, sNameMemory, 0, aiOutArray, ArraySize(aiOutArray), 0, ArraySize(aiOutArray));
 

 Это здесь.

 

Благодарю!

К сожалению не работает функция проверки существования выделенной памяти по имени почему-то.

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

//--------------------------------------------------------------------
#property indicator_chart_window
//--------------------------------------------------------------------
#include <SharedMemoryMT4.mqh>
string sNameMemory = "MyMem";
int aiOutArray[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 195};
//--------------------------------------------------------------------
int init(){ Alert("init");

   bool i;
   i=MemoryCheckName(0, "", sNameMemory);
   Alert(i);
   MemoryClear(0, "", -1, sNameMemory);
   i=MemoryCheckName(0, "", sNameMemory);
   Alert(i);

}
//--------------------------------------------------------------------
int start(){
}
//--------------------------------------------------------------------

Алерт выдает единицы.

 
Andrei01:

Имеем код на базе этого примера https://www.mql5.com/ru/code/10571

Нужно записать и считать массив, но не работает...

что именно не работает? какие ошибки? на какой строке не работает? где журнал, отчет багов?
 
sergeev:
что именно не работает? какие ошибки? на какой строке не работает? где журнал, отчет багов?

Не работает запись и считывание data[3].
 
Andrei01:
Не работает запись и считывание data[3].


код ошибки какой? что возвращает Write? что возвращает Read?

 
sergeev:

код ошибки какой? что возвращает Write? что возвращает Read?

err[0] равно 0 в обеих случаях. Write возвращает 0, а Read возвращает 12.
 
Andrei01:

Благодарю!

К сожалению не работает функция проверки существования выделенной памяти по имени почему-то.

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

Алерт выдает единицы.

Функция проверки существования выделенной памяти Вам не пригодится. Зачем? Можете читать до записи. Всё само выделится сколько надо.

Да и работать она у Вас не будет. Вам доступно только одно имя в каждом пространтстве имён.

Записывать можно сколько угодно массивов. Пишите следующий с нового адреса. 

 
Zhunko:

Функция проверки существования выделенной памяти Вам не пригодится. Зачем? Можете читать до записи. Всё само выделится сколько надо.

Да и работать она у Вас не будет. Вам доступно только одно имя в каждом пространтстве имён.

Записывать можно сколько угодно массивов. Пишите следующий с нового адреса.

А как проверить что массив уже находится в памяти? Например, я хочу сохранить данные во внешней памяти когда делаю перекомпиляцию чтобы потом не инициализировать их заново.

Что значит писать с нового адреса? Пробовал записать другой массив в то же пространство имени, но это не работает.

 
Andrei01:
А как проверить что массив уже находится в памяти? Что значит писать с нового адреса? Пробовал записать другой массив в то же пространство имени, но это не работает.

Чтобы проверить надо его прочитать. Разве есть другой способ?

Вот запись 2-х массивов:

#include <SharedMemoryMT4.mqh> // Заголовочный файл библиотеки "SharedMemoryMT4.dll".
string sNameMemory = "MyMem";
int aiOutArray1[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int aiOutArray2[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int aiIncArray1[10] = {0};
int aiIncArray2[10] = {0};

MemoryWriteIntArray(0, "", -1, sNameMemory, 0, aiOutArray1, ArraySize(aiOutArray1), 0, ArraySize(aiOutArray1));
MemoryWriteIntArray(0, "", -1, sNameMemory, 4 * ArraySize(aiOutArray1), aiOutArray2, ArraySize(aiOutArray2), 0, ArraySize(aiOutArray2));

MemoryReadIntArray(0, "", -1, sNameMemory, 0, aiIncArray1, ArraySize(aiIncArray1), 0, ArraySize(aiIncArray1));
MemoryReadIntArray(0, "", -1, sNameMemory, 4 * ArraySize(aiIncArray1), aiIncArray2, ArraySize(aiIncArray2), 0, ArraySize(aiIncArray2));

Всё же, проще в тестовый скрипт с примерами заглянуть.

Для начала проверить работоспособность компа тестовым скриптом. Там есть видео. Если не работает, то МТ4 стоит на системном диске и/или прав недостаточно. 

 
Andrei01:
err[0] равно 0 в обеих случаях. Write возвращает 0, а Read возвращает 12.


Андрей, как вы можете читать 3 числа, но при этом пытаться вывести на экран четвертое?

вам не кажется что это не логично?