Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 856
  • Last Modified:

Fastest way to move BITMAP data between processes

I am working on a project where I have to move a lot of HBITMAP data between applications. Currently I am using a COPYDATASTRUCT to hold the entire array of data from GetDIBbits then send it using a WM_COPYDATA message. It works well enough but at times I need to move a midsized bitmap several times a second, and the slowdown is noticeable.

Is there some way to write the bitmap data directly to another process or some other "magic" I can use in this situation.
0
mite51
Asked:
mite51
  • 4
  • 3
  • 2
  • +3
1 Solution
 
jhanceCommented:
The most efficient method for sharing large blocks of data between processes is via shared memory.  See the MFC class CSharedFile.  I've not done this without MFC but I believe the MapViewOfFile() API is used.
0
 
mite51Author Commented:
I was avoiding that because I thought the shared file was a file on the hard disk, which would be kinda slow. Of course it could ba a memory mapped file.

Still how much more efficient could it be? I fill in a temporary structure with the data and pass it with WM_COPYDATA where the receiver has to copy it out. I guess I can aviod the step of having to copy it out.

Can I create a hbitmap with the pBits pointer in the memory mapped file? that way all drawing would be rendered directly to the shared memory..? mmmm

Jason
0
 
SChertkovCommented:
You can create COM object what implement IDataObject
in you target application, and register it in
Running Object Table. Source application extract
interface from ROT, query IDataObject and
through it pass hBitmap. IDataObject marshaled by
system and moving bitmap will be transparent.
0
Microsoft Certification Exam 74-409

VeeamĀ® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
MadYugoslavCommented:
I am not sure but you can try to make DLL (some type of data manager). Load DLL in both processes, register them (with function pointers or message identifiers) and comunicate throw DLL functions.
0
 
MadshiCommented:
>> I was avoiding that because I thought the shared file was a file on the hard disk, which would be kinda slow. Of course it could ba a memory mapped file.

No, memory mapped files are not on hard disk (except if you don't have enough RAM). To your information: WM_COPYDATA uses memory mapped files internally. Windows uses memory mapped files everywhere, it's optimized as hell. Using WM_COPYDATA is not ideal because it creates and destroys a new memory mapped file object everytime you use it. If you do it yourself, you can keep the memory mapped file open, which will speed things up in comparison to WM_COPYDATA.

>> Can I create a hbitmap with the pBits pointer in the memory mapped file? that way all drawing would be rendered directly to the shared memory..? mmmm

Hmmm... Sounds like a good idea. Try it out!

Regards, Madshi.
0
 
MadshiCommented:
P.S: Memory mapped files have a fixed size, I hope that is no problem?
0
 
mite51Author Commented:
from MSDN..

Please note that CSharedFile does not use memory-mapped files, and the data cannot be directly shared between processes.

What does that mean?

I have found some useful global/process memory functions. Does anyone have experience with VirtualAllocEx or GlobalAlloc. Could I use these? If I allocate memory in the target processes address space can I directly access it from the former process?
0
 
MadshiCommented:
>> Please note that CSharedFile does not use memory-mapped files, and the data cannot be directly shared between processes.
>> What does that mean?

Don't know. Why not using pure APIs? CreateFileMapping + MapViewOfFile.

>> I have found some useful global/process memory functions. Does anyone have experience with VirtualAllocEx
or GlobalAlloc. Could I use these? If I allocate memory in the target processes address space can I directly access it from the former process?

You can use VirtualAllocEx to allocate memory in the destination process, but only in NT based systems, in win9x this function is not available. You can't directly write to this memory from the source process, but you can use WriteProcessMemory to write to the memory.

GlobalAlloc is useless for your purposes. The shared flags don't work in 32bit.

In win9x you could use undocumented functions to allocate memory in the shared area (which is directly accessible from all processes), but why doing that? Memory mapped files do have *EXACTLY* the same effect. In win9x memory mapped files are nothing but allocated shared memory.

Regards, Madshi.
0
 
BeyondWuCommented:
I think there several method can improve the performance.
First, just like MadYugoslav has said, you can use a dll, and use the share-section.
#pragma data_seg("Shared")
//Here is your entire array of data from GetDIBbits
UCHAR  ibuff[MAXBITMAPSIZE];
#pragma data_seg()
#pragma comment(linker, "/section:Shared,rws")
In your dll, you can export two functions, for example, named Get(Set)SharedDiBbits(..).In your two processes, you should use these methods to get or set DIBbits, now you only need send a notify message when a process prepare the DIBbits, and the other process will use the GetSharedDIBbits to get the data. They use the same buffer, there no data transfer.

Another method i can see is, you can use Read/WriteProcessMemory Api, for example, you can only send a message which take the buffer information in one process, in the other process, you can use ReadProcessMemory get the data directly.

And I also think you can use the mapped-file to share the data just as Madshi has said.

Hope this help.
0
 
mite51Author Commented:
I like the shared data segment in DLLs but is there a way to dynamically allocate the memory? or possibly have a HUGE shared chunk that I can manage. Arrays can only index so much.

Lots of new options tho, thanks
0
 
BeyondWuCommented:
I don't think you can dynamically allocate the memory, if you wanted to use this method you only can use like this:
UCHAR  ibuff[MAXBITMAPSIZE] = {0}; // should be initialized, and the size is fixed!
0
 
mite51Author Commented:
there was some good input and thanx to all but I think I am going to go with a shared mem file. I guess I'll be giving my points to jhance.

Anyway, here is the code I decide to go with which suits my needs farirly well.. IF I can allocate 20 M chucks with it :)

http://www.microsoft.com/MSJ/1198/wicked/wicked1198top.htm
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now