I'm new to shared memory dll and sharing data between processes.
My objective is as follows: I have to put images obtained from 3 different cameras in a shared memory location so that other application can access it (LabView).
I'm obtaining these images from a single exe using the camera API's provided by the manufacturer.
I have been successful in creating a shared memory dll and copying the image from one camera into it using the sample code given here http://msdn.microsoft.com/en-us/library/ms686958%28VS.85%29.aspx and im able to read the image data in the target application.
My question is how do I specify a size for shared memory at runtime? since the image sizes would vary according to the resolution used I want to specify the size from the program that stored the data in shared memory.
Also i want to put the images obtained from 3 cameras in three distinct sections within the shared memory. how can this be achieved?
Apart from sharing data how is it possible to synchronize events between the two process e.g. if the target application wants to grab an image, how can it communicate with the camera application through shared dll.
I'm pretty new to a lot of concepts related to windows. I want to understand these well. Kindly guide me..
In the sample code the shared memory size is set in the DLL's DLL_PROCESS_ATTACH. Doing it there does not permit you to calculate the size at run time.
The program that stores the data into shared memory can set the size of the shared memory by calling CreateFileMapping & MapViewOfFile without using the DLL.
You can define a struct in the first few bytes of the shared memory region that contains the sizes and offsets to the pictures. Other programs can first read these items to determine where the pictures are within shared memory.
Shared memory does not provide messages between processes. That is best done with sockets or a named pipe or by sending WM_COPYDATA to a window (HWND).
Thanks for your reply.
The problem is that my application program cannot access shared memory directly. It can access it only through the functions of a dll. Basically it is Block Diagram Programming if you understand what i mean. Also it can work with only simple data types such int, char, etc. it cannot work with structures or classes.
This is why I'm stuck...
What could be a work around for this??
If your DLL is written in C/C++ then the application program does not need to work with the struct. Only the DLL needs to read the struct. You could also think of the struct as an array of ints: number of pictures, size of first picture, offset to first picture, ... etc. The application program simply asks for picture data; the DLL gets the data.
If you move the CreateFileMapping/CreateViewOfFile calls into a DLL function, instead of at DLL_PROCESS_ATTACH, you can achieve what you want. Just call this function with the needed size to create the shared memory.
There a lot of ways you can make an IPC mechanism in windows.
As you can see from the sample Microsoft provides, there is no synchronized access to the memory. In order to do that you will have to make a synchronization named event, that each of your application will have to open.
Use CreateEvent function with the ManuaResetEvent parameter set to FALSE, or better yet read the documentation yourself.
When your applications will now need to access the memory they must first wait for the event and then modify the memory.
You could also implement different paradigms here, like readers writers.
<QUOTE>My question is how do I specify a size for shared memory at runtime? since the image sizes would vary according to the resolution used I want to specify the size from the program that stored the data in shared memory.</QUOTE>
You can do this yourself, without an implementation from Microsoft. When you create the file mapping, create one big enough to fit you biggest resolution picture.
You can have your library a variable called:
ULONG g_ulCurrentFileMappingSize = 0;
This variable will specify the current size in use of the file mapping object that you use.
You could make 2 functions like
void SetFileMappingObjectSize(ULONG Size)
g_ulCurrentFileMappingSize = Size;
Which will inform your apps how big the current picture is, and how much of the file mapping object should be used. These calls should of course be protected by a synchronization event.
@David: Creating files and accessing them will consume a lot of time and resources. The application is for web inspection of products moving on a conveyor. The images coming from the cameras will be processed to find defects and appropriate action will be taken. So the processing has to be real fast. With and image of around 3-5MB it will take considerable amount of time to move from camera to file and then into the image processing application which will take its own time.We need to do all this within 30ms. So it is pretty tight.
@Scott: I think that should solve the problem. Also will it be a good idea of creating a named file mapping object from the image grabbing application without using a dll and use a dll from the image processing application to open this named file mapping object using OpenFileMapping()?
@Bercea: I will check this CreateEevent() out and see if i can use it effectively. As far as the size specification is concerned i think i'll be able to manage it from the suggestions you guys gave.
Thanks a lot guys for all your help. I'll update you with the progress.
Hey guys thought i'll updateyou.
I have achieved my objective by using a wrapper over the dll's provided by the manufacturer and have been able to synchronize data without any problems for 1 camera. Yet to test it on multiple cameras.
Is there any way of transferring data between two memory locations within the same address space without using the CPU e.g may be using DMA??
DMA usually means a device accesses the memory directly; I'm not sure it's possible to set up a memory-to-memory direct transfer using DMA techniques. However ... if you have a GPU spare, you might get that to do the transfer instead of the CPU. It's not something I've tried, though, so I cannot tell you how to go about it.
Answering policy: see profile.
Hello again. Sounds like you have good progress!
No, DMA is not available for application programs. If you must copy the images memory-to-memory use memcpy or CopyMemory.
But of course it would be better to input the camera data to where you really want it instead of copying it. Can you pass the desired destination address (in the shared memory) to the camera API?
@Scott: No its possible to set the destination address within the API. We can obtained an address to the location where the image has been acquired. So there is going to be atleast one copy routine per camera.
If its possible I want to keep CPU completely out of copy process. The copy routine is executed on a different thread but thats not enough.
David has raised an interesting view. Is it possible to bring GPU into picture?? Because then i can also use it for a lot of image processing stuff...
The question still remains whether or not i can do a memory-memory copy without involving any CPU cycles??
As far as memory transfer is concerned, transferring a picture of 2 or 3 MB is not an issue that might bother you because it can be transferred in a few milliseconds, and the CPU will still be busy with you processing or rendering or what you want to use it, in the rest of the time. As windows is just a GPOS, not a real time operating system you have to cope with that and the fact that you have a user mode application. If you want, you can go deep and create your own device that has it's own memory ranges and use a DMA adapter to make this transfers for you, but as far I can tell there will be no major differences in performance.
Unfortunately for you a GPU cannot make memory transfers and, actually cannot do operations that a CPU can to. A GPU can only be used to make some math calculations like converting 3D vectors to 2D vectors, and are aggravatingly hard to get along to. I believe there are also general purpose GPU's that are not only specialized in graphics processing but, used in research like medicine or very complex simulations. GPU's can have 100 cores and work slightly different that your CPU that carries out instructions for your applications, so as far as I am concerned using a GPU is not an option here, at least for what you want to do.
I am not sure if you are not somehow trying to reinvent the wheel here. What are you constraints and why is copying data using the CPU is not good for you.
I have made a test, and it take about 500 milliseconds to copy 1000 4 MB of memory from one file mapping object to a buffer or vice versa. So that is 5 milliseconds for 40 MB, that is 8 MB in one millisecond of data transfer, or 1 MB on 1/8 milliseconds. If you had tot copy like huge quantities of data, like each file is 1 GB than you should thing of using DMA, or if the biggest overhead is data transfer not the processing, as I see the processing is an issue for you.
Anyway hope you find a way to make it work. Good luck.