Using CreateFileMapping between two programs - C
I have two window form applications written in C, one holds a struct consisting of two integers, another will receive it using the CreateFileMapping.
Although not directly related I want to have three events in place so each of the processes can "speak" to each other, one saying that the first program has something to pass to the second, one saying the first one has closed and another saying the second one has closed.
What would be the best way about doing this exactly? I've looked at the MSDN entry for the CreateFileMapping operation but I'm still not sure as to how it should be done.
I didn't want to start implement开发者_开发问答ing it without having some sort of clear idea as to what I need to do.
Thanks for your time.
A file mapping does not seem like the best way to handle this. It has a lot of overhead for simply sending two integers in one direction. For something like that, I'd consider something like a pipe. A pipe automates most of the other details, so (for example) attempting to read or write a pipe that's been closed on the other end will fail and GetLastError()
will return ERROR_BROKEN_PIPE
. To get the equivalent of the third event (saying there's something waiting) you work with the pipe in overlapped mode. You can wait on the pipe handle itself (see caveats in the documentation) or use an OVERLAPPED
structure, which includes a handle for an event.
In answer to your question of how you WOULD do it if you wanted to used Shared Memory, you could use a byte in the shared memory to communicate between the two processes. Here is some sample code. You can easily replace the wait loops with semaphores
/
/ SharedMemoryServer.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h> // getch()
#include <tchar.h>
#include "Aclapi.h" // SE_KERNEL_OBJECT
#define SM_NAME "Global\\SharedMemTest"
#define SIGNAL_NONE 0
#define SIGNAL_WANT_DATA 1
#define SIGNAL_DATA_READY 2
#define BUFF_SIZE 1920*1200*4
struct MySharedData
{
unsigned char Flag;
unsigned char Buff[BUFF_SIZE];
};
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFileMapping = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, sizeof(MySharedData), SM_NAME);
if (hFileMapping == NULL)
printf ("CreateFileMapping failed");
else
{
// Grant anyone access
SetNamedSecurityInfo(SM_NAME, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, (PACL) NULL, NULL);
MySharedData* pSharedData = (MySharedData *) MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
printf("Waiting for instructions\n");
while (pSharedData->Flag == SIGNAL_NONE) // Wait to be signaled for data
;
if (pSharedData->Flag == SIGNAL_WANT_DATA)
{
printf("Signal for data received\n");
size_t len = sizeof(pSharedData->Buff);
memset (pSharedData->Buff, 0xFF, len);
pSharedData->Flag = SIGNAL_DATA_READY;
printf("Data ready signal set\n");
// Wait for data to be consumed or up to 10 seconds
while (pSharedData->Flag != SIGNAL_NONE)
;
printf("Data consumed signal detected\n");
}
}
_getch();
return 0;
}
The client process would be equivalent but the code in the else case following the call to MapViewOfFile() would look something like this:
pSharedData->Flag = SIGNAL_WANT_DATA; // Signal for data
printf("Signal for data set\n");
while (pSharedData->Flag != SIGNAL_DATA_READY)
;
printf("Data ready signal detected\n");
if (pSharedData->Flag == SIGNAL_DATA_READY)
{
// Dump the first 10 bytes
printf ("Data received: %x %x %x %x %x %x %x %x %x %x\n",
pSharedData->Buff[0], pSharedData->Buff[1], pSharedData->Buff[2],
pSharedData->Buff[3], pSharedData->Buff[4], pSharedData->Buff[5],
pSharedData->Buff[6], pSharedData->Buff[7], pSharedData->Buff[8],
pSharedData->Buff[9]);
}
You can use CreateSemaphore and provide a name for the last parameter to create a named semaphore. Processes can share that semaphore (the other process would use OpenSemaphore). One process signals when the data is ready and the other can wait on it.
Having said this, I have to agree with Jerry that using a pipe might be a lot simpler to get it working. On the other hand, using the shared memory approach with semaphores (or events) may translate more simply to other platforms (e.g., Linux) if it becomes necessary to port it.
精彩评论