-
Memory Mapped File
Hi,
I'm working on an assignment in which I have to use a memory mapped file.
In another assignment I've done this before like this:
Code:
static unsigned long *Buff = NULL;
static HANDLE hFileMap;
// Create File Mapping
hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, maxSize + 1, "memMappedFile");
if (!hFileMap)
{
perror("Unable to create file mapping,Error");
return;
}
// Map View Of File (access memory mapped file and place it in memory)
if ( !(Buff = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) ) )
{
perror("Unable to create view of mapped file,Error");
// Cleanup
CloseHandle(hFileMap);
return;
}
I've used the code above to create a circulair buffer in C.
I'm, however, using using C++ now and the above code (when modified) fails.
I want to map an arraylist:
string neighbourList[5][7]
...to make it available for another proces.
Can someone help me out here?
I'm not sure if I can map a two dimensional array at all, but I'm receiving the following error:
error C2440: '=' : cannot convert from 'LPVOID' to 'std::string [5][7]'
-
But the memory held by an object is not (guaranteed to be) a contiguous chunk of memory. So the string is perhaps a structure like this:
Code:
class string {
char *strdata;
int len;
};
So whilst you can solve the problem of storing a "string array" in the buffer by using (void *) to make it a compatible pointer, you are not storing the string content in the file.
You probably need to rethink this strategy.
--
Mats
-
Don't try to host any std:: objects in shared memory - there's too many things that can and will go wrong. Stick with built-in data types or simple structures composed of built-in types.
gg
-
-
to copy C-strings use strcpy
-
Besided Vart's comment, are you sure this is right:
Code:
MapViewOfFile(hNeighbourListMemMap, FILE_MAP_WRITE, 5, 5, 0)
// This is how MSDN describes the function:
LPVOID WINAPI MapViewOfFile(
__in HANDLE hFileMappingObject, hNeighbourListMemMap OK
__in DWORD dwDesiredAccess, FILE_MAP_WRITE OK
__in DWORD dwFileOffsetHigh, 5 * 4GB ???
__in DWORD dwFileOffsetLow, + 5 bytes.
__in SIZE_T dwNumberOfBytesToMap 0 OK
);
--
Mats
-
I've got a bit of a mess right now...sorry for that!
Code:
static HANDLE hFileMap;
static unsigned long *Buff = NULL;
// Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
if (!hFileMap)
{
perror("Unable to create file mapping,Error");
return;
}
// Map View Of File (access memory mapped file and place it in memory)
if ( !(Buff = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) ) )
{
perror("Unable to create view of mapped file,Error");
// Cleanup
CloseHandle(hFileMap);
return;
}
Buff[0] = 100;
Can someone tell me how the VOID thing works in C++.
I'm getting the following error:
"error C2440: '=' : cannot convert from 'LPVOID' to 'unsigned long *'"
I need to experiment a bit more with MMF after I get this working to ask a proper question. :)
-
MapViewOfFile returns void*, but Buff is unsigned long*.
C++ requires an explicit cast to compile this (because you have two different pointer types).
-
Ok, that works! Thanks!
If anyone can use it, here is the code:
Code:
static HANDLE hFileMap;
static char *Buff = NULL;
// Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
if (!hFileMap)
{
perror("Unable to create file mapping,Error");
return;
}
Buff = static_cast<char*> ( MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) );
Buff[0] = 'H'; // uncomment for client,
Buff[1] = 'i'; // to read from buffer
cout << "Buff0 = " << Buff[0] << ", Buff1=" << Buff[1] << ".\n";
The next step is create a char array...
-
I've got the following code so far for a char array:
Code:
static HANDLE hFileMap;
static char *Buff[2];
// Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
if (!hFileMap)
{
perror("Unable to create file mapping,Error");
return;
}
*Buff = static_cast<char*> ( MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) );
char *test;
test = "hello";
Buff[0] = "hello";
Buff[1] = "world";
cout << "Buff0 = " << Buff[0] << ", Buff1 = " << Buff[1] << ".\n";
...The client does not read anything from the buffer.
If I use
Code:
strcpy(*Buff, test);
...and then read from Buff[0] it works.
But I cannot assign anything to Buff[1]...
Can anyone point me in the right direction? Or am I doing something completely wrong here?
-
What are you doing with multiple pointers? You need only one pointer to the memory area.
Therefore
Code:
static char *Buff[2];
Should be
And once more - do not do this:
Code:
Buff[0] = "hello";
Buff[1] = "world";
You are putting pointers in the shared memory. Pointers which will be invalid in the other process.
Therefore you must use strcpy to copy the string into the shared memory.
-
Ok, I've changed my code.
Now, when I use:
Code:
char *test;
test = "hello";
strcpy(Buff, test);
...It assigns the string, but is there a way to read the string like this:
Buff[0] returns "hello"
Buff[1] returns "world"
When I use Buff[0] it returns the first character and so on.
Also, I can only use one string in Buff, if I use strcpy a second time, it overwrites the first string, whereas by using Buff[0] = "hello" and Buff[1] = "world" I can have multiple strings.
-
You really have no grasp of C-style strings.
So... here you go. Read up.
http://www.cprogramming.com/tutorial/c/lesson9.html
And this:
Code:
char *test;
test = "hello";
strcpy(Buff, test);
Is the same as
Code:
strcpy(Buff, "hello");
And a C-style string is basically an array of chars. So perhaps read a little about arrays, too.
-
I know that both code is the same, and I also know that a string is actually an array of characters.
What I meant was that I want to assign a pointer char array, so I can have some sort of string array to assign multiple string values to the buffer with use of the index like this:
Buff[0] = "hello"
Buff[1] = "world"
I know I can just put all strings behind each other with \0 too, but I like the above method and want to use that in my 'client' too...
Aaah, I'll guess I will have to read some more about C tough.
-
Don't do it. It will never work to assign like that.
strcpy and strcat are your friends. Just as long as you treat the shared memory as char*.