라이브러리: DLL 없는 파일 매핑 - 페이지 9

 

라이브러리 작성자에게 감사드립니다!

모든 데이터를 전송하는 함수를 만들었습니다. 아래 스크립트는 틱의 예에 대한 작업을 보여줍니다.

#include <MemMapLib.mqh>
#include <TypeToBytes.mqh>

// 데이터에 지정된 길이의 메모리를 할당합니다. 
template <typename T>
bool GetFileMemory( CMemMapFile* &FileMemory, const int Amount, const string FileName = "Local\\test" )
{
  FileMemory = new CMemMapFile;
    
  return(FileMemory.Open(FileName, sizeof(T) * Amount + sizeof(int) + HEAD_MEM, modeCreate) == 0);
}

// 메모리에 데이터 쓰기
template <typename T>
void DataSave( CMemMapFile* FileMemory, const T &Data[], const bool FromBegin = true  )
{
  const int Size = ArraySize(Data) * sizeof(T);
  uchar Bytes[];
  
  _ArrayCopy(Bytes, _R(Size).Bytes);              // 수량 기록 
  _ArrayCopy(Bytes, _R(Data).Bytes, sizeof(int)); // 데이터 기록

  if (FromBegin)
    FileMemory.Seek(0, SEEK_SET);

  FileMemory.Write(Bytes, ArraySize(Bytes)); // 모든 것을 메모리에 덤프했습니다.
  
  return;
}

// 메모리에서 데이터를 읽습니다.
template <typename T>
int DataLoad( CMemMapFile* FileMemory, T &Data[], const bool FromBegin = true )
{
  if (FromBegin)
    FileMemory.Seek(0, SEEK_SET);

  uchar Bytes[];
          
  FileMemory.Read(Bytes, sizeof(int));  // 메모리에서 데이터 양 읽기 
  FileMemory.Read(Bytes, _R(Bytes)[0]); // 데이터 자체 가져옴

  _ArrayCopy(Data, Bytes);              // 데이터를 배열에 덤프했습니다.
  
  return(ArraySize(Data));
}

#define  AMOUNT 1000

#define  TOSTRING(A) #A + " = " + (string)(A) + " "

// 진드기 전파의 예
void OnStart()
{  
  CMemMapFile* FileMemory;
  
  if (GetFileMemory<MqlTick>(FileMemory, AMOUNT))
  {
    MqlTick Ticks4Save[];    
    CopyTicks(_Symbol, Ticks4Save, COPY_TICKS_INFO, 0, AMOUNT);
    
    DataSave(FileMemory, Ticks4Save);
    
    MqlTick Ticks4Load[];    
    
    if (DataLoad(FileMemory, Ticks4Load) > 0)    
      Print(TOSTRING((_R(Ticks4Save) == Ticks4Load)) +
            TOSTRING(ArraySize(Ticks4Save)) +
            TOSTRING(ArraySize(Ticks4Load)));
     
    FileMemory.Close();   
  }
  
  delete FileMemory;
}


결과

(_R(Ticks4Save)==Ticks4Load) = true ArraySize(Ticks4Save) = 1000 ArraySize(Ticks4Load) = 1000
 

버전 업데이트

1.02 - 구조체 복사가 유니온으로 변경되었습니다.

파일:
MemMapLib.mqh  31 kb
 
o_o:

버전 업데이트

1.02 - 구조체 복사를 유니온으로 변경했습니다.

파일 교체 및 게시
 
o_o:
여기 클래스에서 파일 크기가 저장되는 헤더에 첫 번째 바이트가 할당된다는 점을 고려하지 않았나요?

제가 제대로 하고 있는지 알려주시겠어요?

두 배로 쓰기/읽기를 하고 싶습니다. mql4는 구조를 서로 복사하는 방법을 모르기 때문에 그렇지 않습니다.

스크립트에는 이러한 유형의 매개 변수를 사용하는 호출이 없었기 때문에 추가했습니다:

	// 64
        long memcpy(double &Destination[], uchar &Source[], int Length);
        long memcpy(uchar &Destination[], double &Source[], int Length);

그리고이 코드는 오류없이 작동했습니다:

void OnStart()
  {
   CMemMapFile hmem;
   long err=hmem.Open("Local\\test",111,modeCreate);

   double src[5]={1.2,3.4,5.6,7.8,9.0};
   int cnt=sizeof(double)*ArraySize(src);
   uchar data[5*8];
   memcpy(data,src,cnt);
   err=hmem.Write(data,ArraySize(data));



   ArrayInitialize(data,0);
   hmem.Seek(0,SEEK_SET);
   err=hmem.Read(data,ArraySize(data));

   ArrayInitialize(src,0);
   memcpy(src,data,cnt);
   
   hmem.Close();
  }


1. 이러한 매개 변수 유형으로 memcpy를 사용할 수 있습니까? "모두 틀렸다면 다시 해보자" 아니요, 두 배를 전혀 쓰거나 읽는 방법은 무엇입니까?

2. 32 비트에서 작동합니까?

 
Denis Lysenko:

이중으로 쓰기/읽기를 하고 싶습니다. mql4는 구조를 서로 복사하는 방법을 모르기 때문에 그렇지 않았습니다.

이제 유니온의 도움으로 구조를 복사할 수 있습니다.


1. 이러한 유형의 매개 변수와 함께 memcpy를 사용할 수 있습니까?

2. 32비트에서도 작동하나요?


 
Customer:

마지막 거래 손실이 발생하면 많이 올립니다.


세션당 2회 거래, 개장 및 종가 예시 개장 8.00 GBP/USD, 종가 16 .00 GBP/USD

 
o_o:

구조는 이제 유니온을 사용하여 복사할 수 있습니다.


어떤 이유로 이전 주석이 지워졌습니다.

   union dbl_u
     {
      double            value;
     };
   union uchar_u
     {
      uchar              value[8];
     };
     
   dbl_u dbl;
   uchar_u chr;
   
   dbl = chr;
'=' - 불법 연산 사용으로 반환됩니다.
 
Denis Lysenko:

어떤 이유로 이전 댓글이 지워졌습니다.

'=' - 불법적인 작업 사용이 표시됩니다.
매뉴얼을 읽어보세요. 노조는 이 방법을 사용하지 않습니다.
 

다음 코드가 작동하지 않는 이유를 이해하도록 도와주세요:

#include <MemMapLib.mqh>

//------------------------------------------------------------------ OnStart
void OnStart()
{
        CMemMapFile hmem;
        long err=hmem.Open("Local\\test",111,modeCreate);
        
        uchar data[],data2[];
        StringToCharArray("0.12243;0.44565;1.32452",data);
        err=hmem.Write(data,ArraySize(data));

   ArrayResize(data2,ArraySize(data));
        ArrayInitialize(data2,0);
        hmem.Seek(0,SEEK_SET);
        err=hmem.Read(data2,ArraySize(data2));
        
        Print("Read result=",CharArrayToString(data2));
        
        hmem.Close();
        
   Print("New cycle of open memory file");
   err=hmem.Open("Local\\test",111,modeOpen);
   Print("err1=",err);  
        
        ArrayInitialize(data2,0);
        hmem.Seek(0,SEEK_SET);
        err=hmem.Read(data2,ArraySize(data2));
        Print("err2=",err);     
        
        Print("after reading data2=",CharArrayToString(data2));
        
        hmem.Close();   
                
}

코드의 결과입니다:

2017.09.20 11:13:54.981 memmap_MY_02_question EURUSD,H1: after reading data2=
2017.09.20 11:13:54.981 memmap_MY_02_question EURUSD,H1: err2=-1
2017.09.20 11:13:54.981 memmap_MY_02_question EURUSD,H1: err1=0
2017.09.20 11:13:54.981 memmap_MY_02_question EURUSD,H1: New cycle of open memory file
2017.09.20 11:13:54.981 memmap_MY_02_question EURUSD,H1: Read result=0.12243;0.44565;1.32452

파일을 다시 연 후 메모리에서 파일 내용을 읽을 수 없는 이유는 무엇인가요?

MT4 터미널에서 스크립트를 실행합니다.

 
Иван:

파일을 다시 연 후 메모리에 있는 파일의 내용을 읽을 수 없는 이유는 무엇인가요?

적어도 컴퓨터를 다시 시작한 후 메모리에 있는 파일을 읽으려고 하지 않는다면...