ライブラリ: DLLなしでのファイルマッピング - ページ 8

 
o_O:
CMemMapFile::Openはエラーコードを 返すか、エラーがない場合は0を返すと書きました。

会話の最初に、私はCMemMapFile::Open関数が何を返すかのスクリーンショットを投稿しました。

それは、エラーがないかのように0でした。


その後、ハンドルがNULLかどうかを確認するために修正しました。

Print(__FILE__,", handle=",MapFile.m_hmem);

その結果

2016.03.04 19:00:00.897 BuyNow Client v 1.03 USDCHF.m,M5: BuyNow Client v 1.03.mq4, handle=8589934592

エラーはないし、ハンドルもある。しかし、誰もファイル・ディスプレイを作成していない...。そして、作成されていないマッピングを開くことは不可能だ。

あるいは、このマッピングは誰かが作成したもので、私が知らないだけかもしれない?

どこかのプログラムがこの正確な名前でディスプレイを作成しているのだろうか?)

#define HADER "BuyNow v10"
CMemMapFile MapFile;
long handl;
int OnInit()
  {

//--- タイマーを作成する
//---
      EventSetMillisecondTimer(Timer);
      handl=MapFile.Open(StringConcatenate("Local\\","_",HADER,"_",GetSymbol(),"_",((ServerAccauntNumber==0) ?  AccountNumber():ServerAccauntNumber)),BUF_SIZE+HEAD_MEM,modeOpen);
      Print(__FILE__,", handle=",MapFile.m_hmem);
//---
   return(INIT_SUCCEEDED);
  }
 

Dmitry Luck'janenko:


あるいは、このマッピングは他の誰かが作成したもので、私はそのことを知らないのだろうか?

あるプログラムが、その正確な名前でマッピングを作ったんだ。)




ソフトウエアはメモリーをそのように扱うだけで、一度に何もクリアしません。 でも、上書きされると開かなくなる。 おそらく、開く間に何もしていないのだろう。
 

優れたライブラリで、ミューテックスと一緒に使ってローカル・コピー機を書いた。

レシーバーにとって重要なコンポーネントとして、私はファイル・サイズを 取得し、そこからループを構築した、

ArrayOutOfRangeや4バイトの不足など、いくつかのバグを見つけた。

修正

//------------------------------------------------------------------ Write
int CMemMapApi::Write(HANDLE64 hmem, const uchar &buf[], DWORD pos, int sz, DWORD &err) // 指定されたバイト数をメモリに書き込む
{
        if (hmem==NULL) return(-1);
        PBYTE64 view=ViewFile(hmem, err); if (view==0 || err!=0) return(-1); // 開いていない場合
        DWORD size=GetSize(hmem, err); if (pos+sz>size) { UnViewFile(view); return(-2); }; // サイズが小さければ終了
        uchar src[]; 
        ArrayResize(src, size+HEAD_MEM); 
        memcpyX(src, view, size+HEAD_MEM); // バイトバッファを取得
        for(int i=0; i<sz; i++)
        { 
        src[pos+i+HEAD_MEM]=buf[i]; // メモリに書き込まれる
        }
        memcpyX(view, src, size+HEAD_MEM); // コピーして戻す
        UnViewFile(view); // ビューを閉じる
        return(0); // OKが返された。
}
//------------------------------------------------------------------ Read
int CMemMapApi::Read(HANDLE64 hmem, uchar &buf[], DWORD pos, int sz, DWORD &err) // 指定されたバイト数をメモリから読み込む
{
        if (hmem==NULL) return(-1);
        PBYTE64 view=ViewFile(hmem, err); if (view==0 || err!=0) return(-1); // 開いていない場合
        DWORD size=GetSize(hmem, err); // サイズを取得
        uchar src[]; 
        ArrayResize(src, size+HEAD_MEM);
        memcpyX(src, view, size+HEAD_MEM); // バイトバッファを取得
        ArrayResize(buf, sz);
        int i=0; 
        for(i=0; i<sz && pos+i<size; i++) 
        {
        buf[i]=src[pos+i+HEAD_MEM]; // バイト読み取り
        //i++;
        }
        UnViewFile(view); // ビューを閉じる 
        return(i); // コピーされたバイト数
}
 

MQL5でMMFを作成し、書き込んでから読み込もうとすると、クリティカル・エラーが発生します。

しかし、別のプログラムでMMFを作成した場合、書き込んだり読み込んだりしようとすると、クリティカルエラーが 発生します。

何が問題なのでしょうか?

 
Alex19791979:

MQL5でMMFを作成し、書き込んでから読み込もうとすると、クリティカル・エラーが発生します。

しかし、別のプログラムでMMFを作成した場合、書き込んだり読み込んだりしようとすると、クリティカルエラーが 発生します。

何が問題なのでしょうか?


テレパス・クラブは、クリティカル・エラーの番号を推測しようと懸命です。

 
Alexey Volchanskiy:

テレパシークラブはクリティカルエラーの番号を推測しようと緊張している。

トピクスターター、テレパスの影響からブロックされる
 

エラーコードのないMT5の重大なエラーメッセージ。 コードがあれば、それが表示されます。

 
Alex19791979:

しかし、別のプログラムでMMFを作成した場合、書き込みや読み込みをしようとするとクリティカル・エラーが 発生します。

何が問題なのでしょうか?

-
- 配列/文字列を扱うすべての機能で、読み書きするために利用可能な割り当て容量をチェックする(2バイトを考慮する)
など。

 

問題は解決しました。

サードパーティのアプリケーションでMMFファイルを読み書きする場合、0からではなく4バイトから書き込む必要があります。

そしてMT5の場合、オフセットが0であっても4バイトはカウントされない。

そのため、サードパーティのプログラムで0バイトから書き込みをさせると、MT5を読もうとしたときにエラーが発生した。

 
Alex19791979:

問題は解決しました。

サードパーティのアプリケーションでMMFファイルを読み書きする場合、0からではなく4バイトから書き込む必要があります。

そしてMT5の場合、オフセットが0であっても4バイトはカウントされない。

そのため、サードパーティのプログラムで0バイトから書き込んでいた場合、MT5を読み込もうとするとエラーが発生しました。

たぶん、クラスの最初のバイトがヘッダ用に割り当てられていて、そこにファイルサイズが 格納されていることを考慮していないのでは?