Tech Support > Microsoft Windows > Development Resources > windows shared memory (data structures across processes)
windows shared memory (data structures across processes)
Posted by rax on August 13th, 2003


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

Posted by Cris Dunbar on August 13th, 2003


rax_s@yahoo.com (rax) wrote in message news:<e7fdc830.0308130900.15d711f3@posting.google. com>...
<snip>

I'll admit I didn't look over the rest too closely ...

Here's a hint: what's the value of sizeof(i)? What's it's value if you
make your string 1024 characters long?

In your structure, i.c is not a string, it's a pointer to char, and
the value of that pointer is what's getting written to your shared
memory. Since that pointer then references memory inside your first
application's memory space, the second app gets garbage when it
dereferences it.

I believe if you simply declare c as char c[BUFFER_SIZE] (and of
course, do away with the malloc), everything will work fine?

Regards.


Similar Posts