如何利用CreateFileMapping API函数进行进程间内存共享?

作者:棋牌游戏开发公司阅读:发布时间:2024-01-22 15:00

摘要:进程间内存共享是在多进程应用程序中非常常见的一种操作,它可以让不同的进程共享同一块内存,从而达到数据共享的目的。在Windows系统中...

 

进程间内存共享是在多进程应用程序中非常常见的一种操作,它可以让不同的进程共享同一块内存,从而达到数据共享的目的。在Windows系统中,CreateFileMapping API函数可以很方便地实现进程间内存共享,本文将从以下几个方面介绍如何利用CreateFileMapping API函数进行进程间内存共享。

如何利用CreateFileMapping API函数进行进程间内存共享?

一、CreateFileMapping API函数简介

CreateFileMapping API函数是一个Windows操作系统提供的函数,其主要作用是创建或打开一个文件映射对象。文件映射对象是一种内存映射文件的句柄,它使得不同的进程可以访问同一块共享内存。

在CreateFileMapping函数的使用过程中,有几个参数是需要特别注意的:

1. hFile:表示要创建或打开的文件句柄。如果hFile参数为INVALID_HANDLE_VALUE,则表示函数将创建一页可供读写的内存。

2. dwProtect:表示内存保护的级别。可以选择的保护级别包括PAGE_READONLY、PAGE_READWRITE、PAGE_WRITECOPY、PAGE_EXECUTE、 PAGE_EXECUTE_READ、 PAGE_EXECUTE_READWRITE、PAGE_EXECUTE_WRITECOPY等。不同的保护级别对共享内存的访问权限是不同的。

3. flProtect:表示文件保护的级别。可以选择的保护级别包括PAGE_READONLY、 PAGE_READWRITE、 PAGE_WRITECOPY、 PAGE_EXECUTE、 PAGE_EXECUTE_READ、 PAGE_EXECUTE_READWRITE、PAGE_EXECUTE_WRITECOPY等。

4. dwMaximumSizeHigh和dwMaximumSizeLow:表示共享内存对象所占用的最大内存大小。如果将这两个参数都设置为0,则表示共享内存对象可以达到最大可用的系统内存大小。

二、如何创建文件映射对象

要创建一个文件映射对象,需要使用CreateFileMapping API函数,并传入相应的参数。下面是一个简单的示例,演示如何创建一个文件映射对象:

```cpp

HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, L"SharedMem");

if (hMapping == NULL)

// 创建共享内存失败

```

在上述代码中,第一个参数传入的是INVALID_HANDLE_VALUE,表示创建一个可供读写的内存页。第二个参数传入的是NULL,表示使用默认安全权限。第三个参数传入的是PAGE_READWRITE,表示内存保护级别为可读可写。第四个参数传入的是0,表示文件映射对象的大小为4096个字节。第五个参数传入的是L"SharedMem",表示创建一个命名为“SharedMem”的文件映射对象。

三、如何打开文件映射对象

在不同的进程之间需要共享同一块内存时,需要使用同一个文件映射对象句柄,而不是在不同的进程中分别创建新的文件映射对象。因此,在不同的进程之间通信时,需要打开一个已存在的文件映射对象。在Windows系统中,可以使用OpenFileMapping API函数来打开已存在的文件映射对象。

下面是一个打开文件映射对象的示例:

```cpp

HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"SharedMem");

if (hMapping == NULL)

// 打开共享内存失败

```

在上述代码中,第一个参数传入的是FILE_MAP_ALL_ACCESS,表示文件映射对象可以使用所有可用的访问权限。第二个参数传入的是FALSE,表示不继承当前进程的安全属性。第三个参数传入的是L"SharedMem",表示要打开的文件映射对象的名称为“SharedMem”。

四、如何将文件映射对象映射到内存

在Windows系统中,可以使用MapViewOfFile API函数将文件映射对象映射到内存,并获取指向内存的指针。在将文件映射对象映射到内存前,需要先获取文件映射对象的句柄。下面是一个将文件映射对象映射到内存的示例:

```cpp

HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"SharedMem");

if (hMapping == NULL)

// 打开共享内存失败

LPVOID lpvAddr = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

if (lpvAddr == NULL)

// 映射内存失败

```

在上述代码中,第一个参数传入的是hMapping,表示要映射的文件映射对象句柄。第二个参数传入的是FILE_MAP_ALL_ACCESS,表示可以使用所有可用的访问权限。第三个参数传入的是0,表示映射的起始偏移量为0。第四个参数也传入的是0,表示映射的内存长度为整个文件映射对象的长度。第五个参数也传入的是0,表示映射的内存起始地址由系统自动分配。

五、如何利用文件映射对象进行进程间通信

在不同的进程之间需要共享同一块内存时,可以使用文件映射对象实现进程间通信。具体来说,可以将需要共享的数据保存在文件映射对象中,不同的进程通过共享这块内存来实现数据的交互。

如何利用CreateFileMapping API函数进行进程间内存共享?

下面是一个利用文件映射对象进行进程间通信的示例:

在进程A中:

```cpp

HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, L"SharedMem");

if (hMapping == NULL)

// 创建共享内存失败

LPVOID lpvAddr = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

if (lpvAddr == NULL)

// 映射内存失败

// 在共享内存中写入数据

strcpy_s((char*)lpvAddr, 4096, "Hello from Process A!");

// 等待进程B读取数据

Sleep(5000);

// 释放映射内存

UnmapViewOfFile(lpvAddr);

// 关闭共享内存句柄

CloseHandle(hMapping);

```

在进程B中:

```cpp

HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"SharedMem");

if (hMapping == NULL)

// 打开共享内存失败

LPVOID lpvAddr = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

if (lpvAddr == NULL)

// 映射内存失败

// 从共享内存中读取数据

printf("%s\n", (char*)lpvAddr);

// 修改共享内存中的数据

strcpy_s((char*)lpvAddr, 4096, "Hello from Process B!");

// 释放映射内存

UnmapViewOfFile(lpvAddr);

// 关闭共享内存句柄

CloseHandle(hMapping);

```

在上述代码中,进程A首先创建一个文件映射对象,并将其映射到内存中,然后向共享内存中写入数据。在这个示例中,我们是将字符串“Hello from Process A!”写入共享内存中。接着,进程A等待5秒钟,让进程B有足够的时间去读取共享内存中的数据。最后,进程A释放映射内存,关闭共享内存句柄。

进程B在启动后,首先打开进程A创建的文件映射对象,并将其映射到内存中。然后,进程B从共享内存中读取数据,并将其打印出来。在这个示例中,输出的字符串应为“Hello from Process A!”。接着,进程B修改共享内存中的数据,并将新的字符串“Hello from Process B!”写入共享内存中。最后,进程B释放映射内存,关闭共享内存句柄。

总结

本文介绍了如何利用CreateFileMapping API函数进行进程间内存共享。通过使用 文件映射对象 可以让不同的进程共享同一块内存,从而实现进程间通信。在具体实现过程中,需要注意传递给CreateFileMapping API函数和OpenFileMapping API函数的参数,如 hFile 、dwProtect、 flProtect 、 dwMaximumSizeHigh 和dwMaximumSizeLow 等。同时通过MapViewOfFile API 函数将数据映射到内存,并实现数据的共享。

  • 本文链接:https://fysfzk.com/hyzx/4807.html

  • 本文由 棋牌游戏开发公司小编,整理排版发布,转载请注明出处。部分文章图片来源于网络,如有侵权,请与先发网络联系删除。
  • 相关推荐

    微信二维码

    clwl6868

    长按复制微信号,添加好友

    微信联系

    在线咨询

    点击这里给我发消息QQ客服专员


    点击这里给我发消息电话客服专员


    在线咨询

    免费通话


    24h咨询☎️:132-5572-7217


    🔺🔺 棋牌游戏开发24H咨询电话 🔺🔺

    免费通话
    返回顶部