Windows共享内存和不同的编译器奇怪的行为

时间:2014-08-06 17:04:03

标签: c++ c visual-c++ gcc shared-memory

我有两个不同的进程使用共享内存相互交互,我发现由于某种原因它没有按预期工作,事实是,当我放置数据时缓冲区由于某种原因填满额外的零进去。这是我做的:

Process1 vc ++(msvc2012活动解决方案平台Win32):

LPTSTR pBuf =(LPTSTR) MapViewOfFile(hMap,   // handle to map object
                        FILE_MAP_ALL_ACCESS, // read/write permission
                        0,
                        0,
                        256);
if(!pBuf)
{
        //handle errors
}
WaitForSingleObject(hExchangeData,INFINITE); //here i'm waiting data from the second process it should be DWORD value

DWORD someValue=0;
CopyMemory((PVOID)&someValue,pMemBuf,sizeof(DWORD)); //i get it and everything is ok, then the second process waits for this process to put some data in
int pBufSize=sizeof(DWORD); //counter
CopyMemory((PVOID)(pBuf+pBufSize),&hHandle1,sizeof(HANDLE));
pBufSize+=sizeof(HANDLE);
CopyMemory((PVOID)(pBuf+pBufSize),&hHandle1,sizeof(HANDLE));
SetEvent(exDone);

以下是使用MinGW编写的第二个过程:线程模型:win32,gcc版本4.8.1(GCC)

 pBuf = (LPTSTR) MapViewOfFile(hMap,
               FILE_MAP_WRITE | FILE_MAP_READ,
               0,
               0,
               256);

   if (pBuf == NULL)
   {
       //handle errors
   }
   DWORD myVal = 228;
   memcpy(pBuf,&myVal,sizeof(DWORD)); //here i wrote some dword in there which first process is successfully receiving
   SetEvent(dwordWritten); 
   int mySize = sizeof(DWORD); // counter
   WaitForSingleObject(handlesWrittine,INFINITE); //waiting for some handles

   CopyMemory((PVOID)&myHandle1,(PVOID)(pBuf+mySize),sizeof(HANDLE));
   mySize += sizeof(HANDLE);
   CopyMemory((PVOID)&myHandle2,(PVOID)(pBuf+mySize),sizeof(HANDLE));

所以基本上在第一个进程(msvc)中我写了两个长度为4个字节的句柄,因为sizeof(HANDLE) =4在两个版本上,我用printf检查,我希望得到4个字节在第二个(mingw + gcc)过程中,但是第一个过程中的内存缓冲区结构看起来像这样

 1234 //dword
 0012  //handle1
 0013  //handle2

但在第二个过程中:

  1234 //dword
  0000  
  0012  //handle1
  0000  
  0013  //handle3

所以从第二个进程最后CopyMemory指令得到0012句柄值。为什么这样不一样?为什么我在第二个过程中获得额外的Zero?我尝试将msvc平台用于BOTH进程并且工作正常,但是使用了mingw,gcc no。

2 个答案:

答案 0 :(得分:2)

这次我看到了实际的问题。

pBuf的类型为LPTSTR。在UNICODE构建中,它是一个简短的*指针。在ANSI构建上,这是一个char *指针。我怀疑你的Visual Studio项目是在构建环境中定义UNICODE而MinGW不是。因此,在第一个代码示例中的CopyMemory调用中的这个表达式:

(pBuf+mySize)

评估通过mySize * 2字节递增pBuf。

简单的解决方法是将pBuf声明为LPSTR类型或char *。

char* pBuf = (char*) MapViewOfFile(hMap,   // handle to map object
                        FILE_MAP_ALL_ACCESS, // read/write permission
                        0,
                        0,
                        256);

应该这样做。

答案 1 :(得分:-1)

有几个问题。

首先,这条线看起来很遥远:

mySize += HANDLE;

这甚至可以编译吗?不打算说mySize += sizeof(HANDLE)

无论如何,你绝对相信MinGW中sizeof(HANDLE)是4吗?我有疑虑。

HANDLE通常在<winnt.h>

中定义如下
typedef void *HANDLE;

因此sizeof(HANDLE)将为4或8,具体取决于您是构建为32位还是64位构建。

我怀疑您的Visual Studio配置是32位模式,因为这是通常的默认设置。而你的MinGW版本是64位的。

如果将Visual Studio项目配置为生成64位版本,则会看到相同的差异。