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

在两个程序之间使用CreateFileMapping-C,c,winapi,shared-memory,C,Winapi,Shared Memory,我有两个用C编写的窗口窗体应用程序,一个保存由两个整数组成的结构,另一个将使用CreateFileMapping接收它 虽然没有直接关系,但我希望有三个事件,这样每个进程都可以相互“说话”,一个说第一个程序有东西要传递给第二个程序,一个说第一个程序已经结束,另一个说第二个程序已经结束 做这件事最好的方法是什么?我已经查看了CreateFileMapping操作的MSDN条目,但我仍然不确定该如何完成 我不想在没有对我需要做什么有明确想法的情况下开始实施它 谢谢您的时间。文件映射似乎不是处理此问题

我有两个用C编写的窗口窗体应用程序,一个保存由两个整数组成的结构,另一个将使用CreateFileMapping接收它

虽然没有直接关系,但我希望有三个事件,这样每个进程都可以相互“说话”,一个说第一个程序有东西要传递给第二个程序,一个说第一个程序已经结束,另一个说第二个程序已经结束

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

我不想在没有对我需要做什么有明确想法的情况下开始实施它


谢谢您的时间。

文件映射似乎不是处理此问题的最佳方法。简单地在一个方向上发送两个整数会有很多开销。对于这样的事情,我会考虑像管子之类的东西。管道会自动处理大部分其他细节,因此(例如)尝试读取或写入另一端已关闭的管道将失败,
GetLastError()
将返回
ERROR\u break\u pipe
。要获得第三个事件的等价物(表示有东西在等待),您需要在重叠模式下使用管道。您可以等待管道句柄本身(请参阅文档中的注意事项),也可以使用重叠的
结构,其中包括事件句柄

文件映射似乎不是处理此问题的最佳方法。简单地在一个方向上发送两个整数会有很多开销。对于这样的事情,我会考虑像管子之类的东西。管道会自动处理大部分其他细节,因此(例如)尝试读取或写入另一端已关闭的管道将失败,
GetLastError()
将返回
ERROR\u break\u pipe
。要获得第三个事件的等价物(表示有东西在等待),您需要在重叠模式下使用管道。您可以等待管道句柄本身(请参阅文档中的注意事项),也可以使用重叠的
结构,其中包括事件句柄

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

话虽如此,我还是同意杰瑞的观点,使用管道可能会简单得多。另一方面,如果有必要对信号量(或事件)进行移植,则使用共享内存方法可以更简单地转换到其他平台(如Linux)。

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


话虽如此,我还是同意杰瑞的观点,使用管道可能会简单得多。另一方面,如果有必要对信号量(或事件)使用共享内存方法,则可以更简单地将其转换为其他平台(如Linux)。

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

/


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

/


这个管道方法似乎比我最初的想法要好得多,你知道有什么资源可以提供更多的例子吗?也就是说,每个windows窗体都在同一个解决方案中的一个单独的项目中。管道是否仍能在这些条件下工作,因为它们彼此不相关并且是分开的。是的,管道可以在不同的程序之间进行通信。不,恐怕我不知道一个真正简单的指南——抱歉。这个管道方法似乎比我最初的想法好得多,你知道有没有提供进一步示例的资源?也就是说,每个windows窗体都在同一个解决方案中的一个单独的项目中。管道是否仍能在这些条件下工作,因为它们彼此不相关并且是分开的。是的,管道可以在不同的程序之间进行通信。不,恐怕我不知道一个真正简单的指南——对不起。
/ 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;
}
        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]);
        }