在两个程序之间使用CreateFileMapping - C.

时间:2010-04-14 21:58:48

标签: c winapi shared-memory

我有两个用C语言编写的窗体应用程序,一个包含一个由两个整数组成的结构,另一个将使用CreateFileMapping接收它。

虽然没有直接关系,但我希望有三个事件,所以每个进程可以互相“说话”,一个说第一个程序有东西要传递到第二个,一个说第一个已关闭,另一个说第二个已关闭。

这样做最好的方法是什么?我已经查看了CreateFileMapping操作的MSDN条目,但我仍然不确定应该如何完成。

我不想在没有清楚了解我需要做什么的情况下开始实施它。

感谢您的时间。

3 个答案:

答案 0 :(得分:4)

文件映射似乎不是处理此问题的最佳方法。只需在一个方向上发送两个整数就有 lot 的开销。对于类似的东西,我会考虑像管子一样的东西。管道自动化大多数其他细节,因此(例如)尝试读取或写入另一端已关闭的管道将失败,GetLastError()将返回ERROR_BROKEN_PIPE。要获得相当于第三个事件(说有等待的东西),你可以在重叠模式下使用管道。您可以等待管道句柄本身(请参阅文档中的警告)或使用OVERLAPPED结构,其中包含事件句柄。

答案 1 :(得分:2)

如果您想使用共享内存,在回答您将如何执行此操作的问题时,可以使用共享内存中的一个字节在两个进程之间进行通信。这是一些示例代码。您可以使用信号量轻松替换等待循环

/

/ 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;
}

客户端进程是等效的,但是在调用MapViewOfFile()之后的else情况下的代码看起来像这样:

        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]);
        }

答案 2 :(得分:0)

您可以使用CreateSemaphore并为最后一个参数提供名称以创建命名信号量。进程可以共享该信号量(另一个进程将使用OpenSemaphore)。一个过程在数据准备就绪时发出信号,另一个过程可以等待数据。

说完这个之后,我不得不同意Jerry的说法,使用烟斗可能会让它变得更加简单。另一方面,如果需要移植信号量(或事件),则可以使用带有信号量(或事件)的共享内存方法更简单地转换到其他平台(例如Linux)。