65.9K
CodeProject 正在变化。 阅读更多。
Home

CMemMapFile v1.41

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (9投票s)

2000 年 3 月 4 日

viewsIcon

189812

downloadIcon

3587

封装内存映射文件的免费 MFC 类。

  • 下载源代码文件 - 17 Kb
  • 引言

    欢迎使用 CMemMapFile,一个封装内存映射文件的免费 MFC 类。


    特点
    历史
    CMemMapFile 类成员
    用法
    联系作者


    特点

    内存映射是 Win32 提供的一种强大机制,用于实现共享内存,还可以通过简单的内存指针来访问文件,而无需实现自己的定制缓冲机制。例如,调用以下代码可以很简单地
    void* lpData = mmf.Open();
    CharUpperBuff((char*) lpData, mmf.GetLength());
    

    将任意长度的文件转换为大写。

    您可能会在以下领域发现其用途:非常大的数据库文件(具有固定记录)、音频处理、字符串操作和图像处理。

    内存映射文件的另一面是实现共享内存。您可能知道,Win32 为每个进程提供独立的地址空间,因此无法在进程边界之间传递普通指针。通过内存映射文件,您可以恢复这种非常有用的机制。

    源代码 zip 文件包含 CMemMapFile 源代码以及一个简单的基于对话框的应用程序,该应用程序演示了该类的所有功能。有关示例程序的更多详细信息,请查看 testmemmap.cpp 中的 BOOL CTestmemmapApp::InitInstance() 函数和 CDialog1 成员函数。


    历史

    V1.0 (1998 年 3 月 31 日)
    • 现在,如果仅需要读取访问权限,类将避免尝试锁定互斥体。
    • 现在用户可以选择指定文件是否应在末尾映射一个 NULL 终止符。当您想对返回的指针使用某些 C 运行时函数时,这可能会很有帮助。

    V1.1 (1998 年 4 月 20 日)

    • 现在使用 GetFileSize() SDK 调用而不是 GetFileInformationByHandle() 来“可靠地”确定文件长度。
    • 在 SDK 函数失败的所有地方都包含了 TRACE 语句以调用 GetLastError()

    V1.2 (1998 年 5 月 29 日)

    • 映射文件现在可以选择命名或不命名。

    V1.3 (1998 年 10 月 22 日)

    • 修复了当类用于共享内存时,在多次调用 CreateMappingName() 中的一个 bug。
    • 以 HTML 文件形式提供新文档。
    • 示例现在标准地随 VC 5 工作区文件一起提供。
    • 演示应用程序清理,包括
      • 将共享的文本量定义为 MAX_EDIT_TEXT 常量,而不是在示例中到处硬编码为 20。
      • 将计时器的创建位置更改为 OnInitDialog()
      • 清理了 OnInitDialog() 中的初始化序列。
      • 现在使用 _tcscpy() 而不是 _tcsncpy() 来确保数组以 null 结尾。
      • 修复了导致资源编译失败的 resource.h
      • 删除了 resource.h 中不必要的符号。
      • 优化了 OnTimer() 代码的工作方式,仅在 MMF 中的文本发生更改时才更新文本。这意味着您可以连续输入编辑控件。

    V1.4 (1999 年 3 月 30 日)

    • 帮助文件样式微调。
    • 代码现在符合 UNICODE 标准,并提供了构建配置。
    • 代码现在支持 Windows 2000 和 NTFS 5 卷提供的可增长内存映射文件。
    • 添加了文件句柄和文件映射句柄的访问器函数。

    V1.41 (1999 年 4 月 21 日)

    • 添加了代码以解决 Windows 中尝试在 Windows 95 或 98 上内存映射零长度文件的一个 bug。


    CMemMapFile 类成员

    CMemMapFile
    ~CMemMapFile
    MapFile
    MapMemory
    MapExistingMemory
    打开
    Close
    UnMap
    IsOpen
    GetLength
    Flush
    GetMappingName
    GetFileHandle
    GetFileMappingHandle


    CMemMapFile::CMemMapFile

    CMemMapFile();

    备注
    类的标准构造函数。


    CMemMapFile::~CMemMapFile

    ~CMemMapFile();

    备注
    类的标准析构函数。调用 UnMap() 函数。


    CMemMapFile::MapFile

    BOOL MapFile(const CString& sFilename, BOOL bReadOnly = FALSE, DWORD dwShareMode = 0, BOOL bAppendNull = FALSE, BOOL bNamed = FALSE, BOOL bGrowable = FALSE);

    返回值
    如果文件成功映射,则返回 TRUE,否则返回 FALSE。

    参数

    • sFilename -- 要内存映射的文件名。
    • bReadOnly -- 如果您不打算修改文件,则设置为 TRUE。
    • dwShareMode -- 调用 CreateFile() 时使用的共享标志。如果您想使用 MMF 技术映射文件,但允许其他进程以只读方式访问它,这可能会很有用。
    • bAppendNULL -- 设置为 TRUE,它将在文件映射的末尾添加一个双 null。如果您想将数据视为以 null 结尾的 ASCII 或 Unicode 字符数组,这可能会很有用。
    • bNamed -- 确定您是否要使内存映射文件命名。通常,当您映射文件时,不需要这样做,因为 MMF 不用于共享内存。
    • bGrowable -- 如果您将此值设置为 TRUE,则底层文件将被设置为“稀疏”文件。在内存映射文件的上下文中,这意味着当您尝试写入文件末尾时,不会发生访问冲突,而是操作系统会为您自动增长文件。请注意,这仅在 Windows 2000(也称为 NT 5)的 NTFS 5 卷上受支持。这在您想要使用内存映射文件来实现诸如直接磁盘音频录制等功能时很有用,而您不想预先分配特定大小的磁盘文件。有关 Windows 2000 中这项新功能的更多信息,请参阅 MSDN 或 Platform SDK。

    备注
    映射文件系统文件。请注意,尝试在只读模式下修改文件映射将导致访问冲突。


    CMemMapFile::MapMemory

    BOOL MapMemory(const CString& sName, DWORD dwBytes, BOOL bReadOnly = FALSE);

    返回值
    如果内存成功映射,则返回 TRUE,否则返回 FALSE。

    参数

    • sName -- 要使用的名称。
    • dwBytes -- 要映射的大小。
    • bReadOnly -- 用法与 MapFile() 中相同。

    备注
    这会创建一个共享内存块。


    CMemMapFile::MapExistingMemory

    BOOL MapMemory(const CString& sName, DWORD dwBytes, BOOL bReadOnly = FALSE);

    返回值
    如果内存成功映射,则返回 TRUE,否则返回 FALSE。

    参数

    • sName -- 要使用的名称。
    • dwBytes -- 要映射的大小。
    • bReadOnly -- 用法与 MapFile() 中相同。

    备注
    此函数与 MapMemory() 非常相似,不同之处在于如果映射已创建,它将失败。此函数可用于连接到现有的共享内存,或者用于检测您的程序是否是第一个实例。


    CMemMapFile::Open

    LPVOID Open(DWORD dwTimeout = INFINITE);

    返回值
    指向内存映射文件中存储的数据的指针。

    参数

    • dwTimeout -- 如果映射已被另一个线程或进程打开,则等待的毫秒数。

    备注
    调用 MapFile()MapMemory()MapExisitingMemory() 后,您可以调用此函数来实际获取指向数据的指针。在内部,该类使用互斥体来同步对内存的访问,因此您不必担心使用该类时的线程同步问题。如果您使用默认值,则如果另一个线程正在使用该对象,您的线程将无限期挂起。


    CMemMapFile::Close

    BOOL Close();

    备注
    这是 Open() 函数的对应函数,每个 Open 调用都应该有一个匹配的 Close 调用。调用 Close 后,您可以再次调用 Open 来获取指针。


    CMemMapFile::UnMap

    void UnMap();

    备注
    这将取消映射对象并释放所有文件句柄和同步对象。您可以将此函数视为 Map...() 函数的对应函数。如果您忘记手动调用它,析构函数也会调用此函数。


    CMemMapFile::IsOpen

    BOOL IsOpen() const;

    返回值
    如果此对象已打开,则返回 TRUE,否则返回 FALSE。


    CMemMapFile::GetLength

    DWORD GetLength() const;

    返回值
    映射对象的长度。这是您可以索引到映射指针的最大偏移量(以字节为单位)。超出此边界将导致访问冲突。如果您映射了一个文件,那么这将对应于文件大小。


    CMemMapFile::Flush

    BOOL Flush();

    返回值
    如果刷新成功,则返回 TRUE,否则返回 FALSE。

    备注
    将映射对象刷新到磁盘。


    CMemMapFile::GetMappingName

    CString GetMappingName() const;

    返回值
    此对象在操作系统中已知的名称(作为 CString)。


    CMemMapFile::GetFileHandle

    HANDLE GetFileHandle() const;

    返回值
    此内存映射实例封装的文件句柄。如果此函数用于共享内存而不是文件系统上的文件,则返回的值将是 INVALID_HANDLE_VALUE。


    CMemMapFile::GetFileMappingHandle

    HANDLE GetFileMappingHandle() const;

    返回值
    此内存映射实例封装的文件映射句柄。



    用法

    包含了一个简单的基于对话框的应用程序,演示了内存映射文件的两个主要功能,即将文件系统文件映射到指针以及实现共享内存。有关示例程序的更多详细信息,请查看 testmemmap.cpp 中的 CTestmemmapApp::InitInstance() 函数和 CDialog1() 成员函数。

    要在您的项目中 MMF 简单地将 memmap.cpp 从演示应用程序包含到您的应用程序中,并在您想使用该类的任何文件中 MMF #include "memmap.h"


    联系作者

    PJ Naughter
    电子邮件: pjn@indigo..ie
    网站:http://www.naughter.com
    1999 年 4 月 21 日


    © . All rights reserved.