I have 2 processes one which writes to a shared memory and another
which reads from it.
This works fine for simple data types. However when I use pointers -
it fails. So I tried to use MapViewOfFileEx and explicitly used the
base address for the second process:
//Writer Program
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
char * lpcTheFile = "test.txt";
//The data structure which is exchanged
//I am writing a = 3, b = 'a', and c a string - "abcd"
typedef struct mystruct {
int a;
char b;
char *c;
} mystruct_t;
int main(void) {
HANDLE hMapFile;
HANDLE hFile;
DWORD dBytesWritten; // number of bytes written
hFile = CreateFile(lpcTheFile,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE){
printf("hFile is NULL\n");
printf("Target file is %s\n", lpcTheFile);
return 1;
}
//I am writing a = 3, b = 'a', and c a string - "abcd"
mystruct_t i;
i.a = 3;
i.b = 'a';
cout << "sizeof i = " << sizeof(i) << endl;
i.c = (char *) malloc(4*sizeof(char));
i.c[0] = 'a';
i.c[1] = 'b';
i.c[2] = 'c';
i.c[3] = 'd';
cout << "sizeof i = " << sizeof(i) << endl;
int count = 0;
if ( 0 == WriteFile(hFile, &i, sizeof(i), &dBytesWritten, NULL)) {
cout << "ERROR1\n";
}
count = dBytesWritten + count;
cout << "bytes written = " << count << endl;
hMapFile = CreateFileMapping(hFile, // current file handle
NULL, // default security
PAGE_READWRITE, // read/write permission
0, // max. object size
0, // size of hFile
"MyFileMappingObject"); // name of mapping object
if (hMapFile != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
printf ("Hmap already exists");
return 2;
}
if (hMapFile == NULL)
{
printf("Could not create file mapping object.");
return 3;
}
LPVOID lpMapAddress;
LPVOID lpStartAddress;
lpMapAddress = MapViewOfFileEx(hMapFile, // handle to mapping object
FILE_MAP_ALL_ACCESS, // read/write permission
0, // max. object size
0, // size of hFile
0,
0); // map entire file
printf("%d\n",lpMapAddress);
if (lpMapAddress == NULL)
{
printf("Could not map view of file.");
}
if (NULL == UnmapViewOfFile(lpMapAddress)) {
printf ("no unmap\n");
} getch();
}
The lpMapAddress was printed as something: 3211264 - and this program
is still running (getch).
Now I ran another program which mapped the file using 3211264 as base:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
char * lpcTheFile = "reader.txt";
typedef struct mystruct {
int a;
char b;
char *c;
} mystruct_t;
int main(void) {
HANDLE hMapFile;
LPVOID lpMapAddress;
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // read/write
permission
FALSE, // Do not inherit the name
"MyFileMappingObject"); // of the mapping object.
if (hMapFile == NULL)
{
printf("Could not open file mapping object.");
}
LPVOID pointerReturned;
//BASE HARDCODED
pointerReturned = MapViewOfFileEx(hMapFile, // handle to mapping
object
FILE_MAP_ALL_ACCESS, // read/write permission
0, // max. object size
0, // size of hFile
0,
(void *)3211264);
if (lpMapAddress == NULL)
{
printf("Could not map view of file.");
}
mystruct_t localCopyOfStruct;
::CopyMemory(&localCopyOfStruct, pointerReturned,
sizeof(mystruct_t));
cout << localCopyOfStruct.a << endl;
cout << localCopyOfStruct.b << endl;
cout << localCopyOfStruct.c[0] << endl;
cout << localCopyOfStruct.c[1] << endl;
cout << localCopyOfStruct.c[2] << endl;
cout << localCopyOfStruct.c[3] << endl;
}
The a and b (static data types were OK) - however for the pointer I
got some junk values printed.
Can anyone let me know what I am doing wrong? Or have I got the whole
thing wrong?! Without using based pointers - is there no way of using
shared memory as an IPC in windows for data structures with pointers
(and without having to implement a heap)?
Regards,
Rax