且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

以最有效的方式在跨进程发送图像

更新时间:2023-11-25 15:41:22

好像内存映射文件和管道是正确的方法。这不是太糟糕,因为这两个进程已经共享了一个MMF和两个管道(用于双向通信)。唯一要解决的问题是如何尽可能少地复制数据。

Ok it seems as if memory mapped files and pipes are the right way to go. That is not too bad because the two processes already share a MMF and two pipes (for bidirectional communication). The only thing left to solve was how to pass the data with as little copy operations as possible.

工作相当好的设计如下(顺序流程):

The design which works quite well looks as follows (sequential flow):

进程1(想要图像)


  • 给过程2(通过管道1)发送信号以将图像存储在共享内存中

  • go睡觉并等待响应(阻止从管道2读取)

过程2(提供图像)


  • 信号(通过管道1)唤醒并告诉硬件设备到HDC 1(这是由共享内存支持,见下文)

  • 给出过程1(通过管道2)的信号

  • 进入睡眠状态并等待新工作(通过管道1)

过程1(想要图像)


  • 信号(通过管道2)唤醒和绘画从共享内存到目标HDC 2

现在通过共享内存传输图像(我的目标是使用不超过一个副本操作):

Now for the image transfer via shared memory (my goal was to use not more than one additional copy operation):

进程2通过 Cr创建一个 HBITMAP eateDIBSection 并提供文件映射的句柄和映射视图的偏移量。因此,图像数据存在于共享存储器中。这将创建一个 HBITMAP ,它被选入HDC 1(也由过程2创建),并从现在开始使用过程2.

Process 2 creates a HBITMAP via CreateDIBSection and provides the handle of the file mapping and the offset of the mapped view. Thus the image data lives in the shared memory. This creates an HBITMAP which is selected into HDC 1 (which is also created by process 2) and which will be used from now on by process 2.

进程1使用 StretchDIBits 指向映射视图的内存(如 here )。这似乎是将内存中的位直接转换为另一个HDC(在本例中为HDC 2)的唯一功能。其他功能会将它们首先复制到一些中间缓冲区,然后才能将它们从那里转移到最终的HDC。

Process 1 uses StretchDIBits with a pointer to the mapped view's memory (as described here). This seems to be the only function for getting bits from memory directly into another HDC (in this case HDC 2). Other functions would copy them first into some intermediary buffer before you could transfer them from there to the final HDC.

所以最终似乎需要传输的位是是一开始的两倍。但是我认为这是一样好,除非在进程之间共享GDI句柄是可能的。

So in the end it seems the bits needed to be transferred are about twice as much as in the beginning. But I think this is as good as it gets unless sharing GDI handles between processes would be possible.

注意:我使用管道而不是信号,因为我需要传输一些额外的数据也是。

Note: I used pipes instead of signals because I need to transfer some additional data, too.