ライブラリ: 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:

最後の取引で損失が出た場合、ロットを引き上げる


1セッションにつき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ターミナルでスクリプトを実行しています。

 
Иван:

メモリ上のファイルを再度開いた後、そのファイルの内容が読めないのはなぜですか?

少なくとも、コンピュータを再起動した後にメモリ上のファイルを読もうとはしないはずだが...。