资料库: 无需 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:

心灵感应者俱乐部正在努力猜测关键错误的数字。

topikstarter被阻挡在心灵感应影响之外
 

MT5关键错误信息 没有错误代码。 如果有代码,就会显示出来。

 
Alex19791979:

但是,如果我用另一个程序创建 MMF,当我尝试写入或读取时,就会出现严重错误

问题出在哪里?

- 检查打开文件
时是否出错 - 检查在处理数组/字符串的所有功能中用于读/写的可用分配容量(考虑 2 字节)
等。

 

问题解决了。

使用第三方应用程序写入和读取 MMF 文件必须从 4 字节开始,而不是从 0 开始。

而对于 MT5,即使偏移量为 0,也不计算 4 字节。

这就是为什么当第三方程序从 0 字节开始写入时,在尝试读取 MT5 时会出现错误。

 
Alex19791979:

问题解决了。

使用第三方应用程序写入和读取 MMF 文件必须从 4 字节开始,而不是从 0 开始。

而对于 MT5,即使偏移量为 0,也不计算 4 字节。

这就是为什么当我使用第三方程序从 0 字节开始写入时,当我尝试读取 MT5 时会出现错误的原因。

也许你没有考虑到,类中的第一个字节是分配给头部的,文件大小 存储在头部?