Reputation: 696
I have a Memory mapped file
and corresponding MapViewOfFile
handle. The memory mapped file
will contain data in two parts:
unsigned int
specifying the length of actual dataFor e.g. if the length of my actual data is 10
characters, the memory mapped file would be like:
10
abcdefghij
where abcdefghij
is the data I want and there will be a newline b/w the length number and data. I am also free to use any other delimiter if needed.
Now I want to read the unsigned int
first in order to be able to read the actual data. I am thinking of memcpy
but I am not sure how can I get the exact unsigned int value as I think memcpy
copies character by character. How can I extract 10
as it is from the content?
Upvotes: 1
Views: 90
Reputation: 6690
You can do like so:
#include "windows.h"
#include <iostream>
int main() {
const size_t buffer_size = 4098;
const char* name = "my_shared_memory"; //sm name
HANDLE file = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffer_size, name);
LPVOID region = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, buffer_size);
const char* const msg = "this is my data"; //this is the string you want to pass
const int msg_size = strlen(msg) + 1; //this is the size of the string data with \0
const int total_size = msg_size + sizeof(int); //the total size of your data: the size of the string and the string by itself
char* const data = (char*)malloc(total_size); //get some memory to place this data
((int*)data)[0] = msg_size; //set the first part of the data with the string msg size
memcpy(data + sizeof(int), msg, msg_size); //set the msg by it self just after the size
CopyMemory(region, data, total_size); //put on sm
const int retrieved_size = ((int*)region)[0]; //retrieves the size of the msg from the sm
char* const retrieved_msg = (char*)malloc(retrieved_size); //alloc some space for receive the msg with the retrieved size
memcpy(retrieved_msg, (char*)region + sizeof(int), retrieved_size); //set the msg in the previous allocated memory
std::cout << retrieved_msg << std::endl; //prints the msg
free(data);
free(retrieved_msg);
}
In this question you have some solutions to check for endianess. Then you can use one more byte to store this information if necessary. If endianess is different, you can swap bytes.
Solution for Josh comment:
For ASCII encoded size, instead of putting on memory the size int binary encoded, you can save as if it were a string:
const int max_digits_size = 3;
char number[max_digits_size + 1];
sprintf(number, "%d", msg_size);
//your total_size is now (max_digits_size + 1) + msg_size
//first you retrieve from sm the number as string in number_memcopied var, then you convert:
const int retrieved_size = strtol(number_memcopied, NULL, 10);
Upvotes: 1