在Windows下使用共享内存。 如何传递不同的数据

发布于 2024-07-15 19:43:08 字数 405 浏览 4 评论 0原文

我目前尝试使用 Windows CreateFileMapping 机制实现一些进程间通信。 我知道我需要首先使用 CreateFileMapping 创建一个文件映射对象,然后使用 MapViewOfFile 创建指向实际数据的指针。 然后,该示例使用 CopyMemory 将数据放入映射文件中。

在我的应用程序中,我有一个图像缓冲区(1 MB 大),我想将其发送到另一个进程。 所以现在我查询指向图像的指针,然后将整个图像缓冲区复制到映射文件中。 但我想知道这是否真的有必要。 是否可以只复制共享内存中指向图像缓冲区数据的实际指针? 我尝试了一下但没有成功。

I currently try to implement some interprocess communication using the Windows CreateFileMapping mechanism. I know that I need to create a file mapping object with CreateFileMapping first and then create a pointer to the actual data with MapViewOfFile. The example then puts data into the mapfile by using CopyMemory.

In my application I have an image buffer (1 MB large) which I want to send to another process. So now I inquire a pointer to the image and then copy the whole image buffer into the mapfile. But I wonder if this is really necessary. Isn't it possible to just copy an actual pointer in the shared memory which points to the image buffer data? I tried a bit but didn't succeed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

浮萍、无处依 2024-07-22 19:43:08

不同的进程有不同的地址空间。 如果将一个进程中的有效指针传递给另一个进程,它可能会指向第二个进程中的随机数据。 因此,您必须复制所有数据。

Different processes have different address spaces. If you pass a valid pointer in one process to another process, it will probably point to random data in the second process. So you will have to copy all the data.

故人如初 2024-07-22 19:43:08

强烈建议您使用Boost::进程间。 它有很多好处来管理此类内容和内容。 甚至包括一些特殊的 Windows 专用功能,以防您需要与使用特定 Win32 功能的其他进程进行互操作。

最重要的是使用 偏移指针而不是常规的指针。 偏移指针基本上是相对指针(它们存储指针所在位置和所指向事物所在位置之间的差异)。 这意味着即使两个指针映射到不同的地址空间,只要映射在结构上相同就可以了。

我使用过各种带有偏移智能指针的复杂数据结构,它的工作方式非常神奇。

I strongly recommend you use Boost::interprocess. It has lots of goodies to manage this kind of stuff & even includes some special Windows-only functions in case you need to interoperate w/ other processes that use particular Win32 features.

The most important thing is to use offset pointers rather than regular pointers. Offset pointers are basically relative pointers (they store the difference between where the pointer is and where the thing pointed to is). This means that even if the two pointers are mapped to different address spaces, as long as the mappings are identical in structure then you are fine.

I've used all kinds of complicated data structures with offset smart pointers and it worked like a charm.

青瓷清茶倾城歌 2024-07-22 19:43:08

共享内存并不意味着发送和接收数据。 它是为多个进程创建的内存,没有违规。 为此,您必须遵循一些机制(例如锁),以便数据不会损坏。

在进程 1 中:

CreateFileMapping() :它将使用最后一个参数中提供的名称创建共享内存块(如果它尚不存在)并返回一个句柄(您可以将其称为指针) ,如果成功的话。

MapViewOfFile() :它将这个共享块映射(包含)到进程地址空间中并返回一个句柄(同样可以说是一个指针)。

通过 MapViewOfFile() 返回的指针,只有您可以访问该共享块。

在进程2中:

OpenFileMapping():如果通过CreateFileMapping()成功创建了共享内存块,则可以使用相同的名称(用于创建共享内存块的名称)内存块)。

UnmapViewOfFile() :它将取消映射(您可以从该进程地址空间中删除共享内存块)。 当您使用完共享内存(即访问、修改等)后,请调用此函数。

Closehandle() :最终将共享内存块与进程分离,用 OpenFileMapping() 或 CreateFileMapping() 返回的参数、句柄调用此函数。

尽管这些函数看起来很简单,但如果没有正确选择标志,行为就会很棘手。
如果您希望读取或写入共享内存,请在 CreateFileMapping() 中指定 PAGE_EXECUTE_READWRITE

成功创建共享内存后,每当您希望访问共享内存时,请在 MapViewOfFile() 中使用 FILE_MAP_ALL_ACCESS

最好在 OpenFileMapping() 中指定 FALSE(不从父进程继承句柄),因为这样可以避免混淆。

Shared Memory doesn't mean sending and receiving of Data. Its a memory created for number of processes without violation. For that you have to follow some mechanisms like locks so that the data will not corrupt.

In process 1 :

CreateFileMapping() : It will create the Shared Memory Block, with the name provided in last parameter, if it is not already present and returns back a handle (you may call it a pointer), if successful.

MapViewOfFile() : It maps (includes) this shared block in the process address space and returns a handle (again u can say a pointer).

With this pointer returned by MapViewOfFile() only you can access that shared block.

In process 2 :

OpenFileMapping() : If the shared memory block is successfully created by CreateFileMapping(), you can use it with the same name (name used to create the shared memory block).

UnmapViewOfFile() : It will unmap (you can remove the shared memory block from that process address space). When you are done using the shared memory (i.e. access, modification etc) call this function .

Closehandle() : finally to detach the shared memory block from process , call this with argument,handle returned by OpenFileMapping() or CreateFileMapping().

Though these functions look simple, the behaviour is tricky if the flags are not selected properly.
If you wish to read or write shared memory, specify PAGE_EXECUTE_READWRITE in CreateFileMapping().

Whenever you wish to access shared memory after creating it successfully, use FILE_MAP_ALL_ACCESS in MapViewOfFile().

It is better to specify FALSE (do not inherit handle from parent process) in OpenFileMapping() as it will avoid confusion.

别理我 2024-07-22 19:43:08

可以获取共享内存,以便在 Windows 的 2 个进程上使用同一地址。 它可以通过多种技术来实现。

使用 MapViewOfFileEx,这是来自 MSDN 的重要专家。

如果建议的映射地址是
提供后,文件被映射到
指定地址(向下舍入到
最近的 64K 边界)如果有
指定的地址有足够的空间
地址。 如果没有足够的
地址空间,函数失败。

通常,建议的地址是
用于指定文件应该是
映射到多个相同的地址
流程。 这需要区域
地址空间可供所有人使用
涉及的流程。 没有其他记忆
分配可以发生在
用于映射的区域,
包括使用 VirtualAlloc
或 VirtualAllocEx 函数来保留
内存。

如果lpBaseAddress参数
指定基偏移量,函数
如果指定的内存成功
区域尚未被使用
调用过程。 系统没有
确保同一内存区域
可用于内存映射文件
在其他 32 位进程中。

另一种相关技术是使用带有标记为 Read + Write + Shared 的 DLL。 在这种情况下,操作系统几乎会为您和加载 DLL 的任何其他进程执行 MapViewOfFileEx 调用。

您可能必须将 DLL 标记为固定加载地址,不可重定位等......自然。

You CAN get shared memory to use the same address over 2 processes for Windows. It's achieveable with several techniques.

Using MapViewOfFileEx, here's the significant experpt from MSDN.

If a suggested mapping address is
supplied, the file is mapped at the
specified address (rounded down to the
nearest 64K-boundary) if there is
enough address space at the specified
address. If there is not enough
address space, the function fails.

Typically, the suggested address is
used to specify that a file should be
mapped at the same address in multiple
processes. This requires the region of
address space to be available in all
involved processes. No other memory
allocation can take place in the
region that is used for mapping,
including the use of the VirtualAlloc
or VirtualAllocEx function to reserve
memory.

If the lpBaseAddress parameter
specifies a base offset, the function
succeeds if the specified memory
region is not already in use by the
calling process. The system does not
ensure that the same memory region is
available for the memory mapped file
in other 32-bit processes.

Another related technique is to use a DLL with a section marked Read + Write + Shared. In this case, the OS will pretty much do the MapViewOfFileEx call for you and for any other process which loads the DLL.

You may have to mark your DLL to a FIXED load address, not relocateable etc.. naturally.

萌无敌 2024-07-22 19:43:08

您可以使用指针编组。

You can use Marshalling of pointers.

请帮我爱他 2024-07-22 19:43:08

如果可能的话,最好将图像数据直接加载/生成到共享内存区域。 这消除了内存复制并将其直接放置在需要的位置。 当它准备好时,您可以向另一个进程发出信号,为其提供数据开始的共享内存中的偏移量。

If it's possible, it would be best to have the image data loaded/generated directly into the shared memory area. This eliminates the memory copy and puts it directly where it needs to be. When it's ready you can signal the other process, giving it the offset into your shared memory where the data begins.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文