PDA

View Full Version : how to write a structure in a shared mem segment.



nass
25th September 2006, 11:58
hi all,
i am running slackware linux and need to use some function that will
will enable me to write and read a STRUCT from a shared mem segment..
i am using open() , to open a file (and get the file descriptor fd returned), and then use mmap to get a void* file_memory pointer.

function fwrite() (from stdio.h) doesn't work cause it can write to a file (ie needs a FILE* nor a void* and casting in this case makes the executable crash), nor does write() (from unistd.h), ie the linux standard write function, that needs as input the file decriptor (int) fd instead of the (void*) file_memory pointer...

and i don't think i can use sprintf because it needs you to define the type of variable you are giving as an argument to it (%d for decimal, %f for float, %p for pointer, %s for string etc..) and i do not know how to 'define' the structure that i want to save... or am i wrong in thinking that and there is a type i can use to store my structure?
is there any other way?

thank you for your help
nass

wysota
25th September 2006, 12:14
You should operate on it as on any other structure - fill it field by field (byte by byte) using regular memory-manipulating operations, like:


struct myStruct *ptr = (myStruct*)file_memory;
ptr->field1 = 1;
ptr->field2 = 2;

For simple structures (meaning ones that consist only of primitive types) this should be enough.

nass
25th September 2006, 12:23
it could be .. here is the catch however:
this is shared mem right? because i need variable values from my executable to be accessed by another.
so i need to be able to lock the shared memory segment....

on top of that and probably more important..
in this 'saveVariables' function there is a switch statement... in each case (depending on which part of my code calls it, different structures (basically groups of variables) need to be stored in different locations in the shared memory segment, so that they will not be overwritten..
you think it would we possible and sufficient if i re-wrote your code like:

struct myStruct *ptr = (myStruct*) (file_memory+anOffset);
ptr->field1 = 1;
ptr->field2 = 2;

or that would just make the compiler go crazy?
nass

wysota
25th September 2006, 12:26
you think it would we possible and sufficient if i re-wrote your code like:

struct myStruct *ptr = (myStruct*) (file_memory+anOffset);
ptr->field1 = 1;
ptr->field2 = 2;


Yes, of course. Shared memory segment is just an array of bytes. You can treat it as of type unsigned char* and you can operate on it like on any other array. So file_memory+anOffset is equal to file_memory[anOffset] which is quite fine :)

nass
25th September 2006, 12:40
nope seems to be in a prob the compiler..(g++ that is )
i use slackware linux 10.2 and the qt 3-3-4 that came with it.

i have the code
struct manualStruct *manualVar=(manualStruct*)(file_memory + 0xC5);

and get the compiler error:

error: pointer of type `void *' used in arithmetic

nass
25th September 2006, 12:53
cool i found the answer as to why this is
basically a void* can not be dereferenced because it has no type...
so trying to offest a void* the compiler didn't know the base unit of offset (ie for a char the offseting is 1byte, for int its 4bytes, for double 64bytes).. so basically i cast the void* to char* in order to do the offset (since i know the offset i need in single byte units), then recast it to myStruct*...
lets see it its gonna save though..

nass
26th September 2006, 12:36
ok i have created a shared memory segment and can save data into it.. i can check because the segment is directly connected to a file in the disk. so yes i have verified data (bytes really) is written into the memory. the problem is reading...
basically just like in saving i create the same exact structure:
struct manualStruct {
Q_UINT8 mC1St;
Q_UINT8 mC2St;
Q_UINT8 mC3St;
};
and then
struct manualStruct *manualVar=(manualStruct*)((char*)file_memory + 0xC5);
basically file_memory is a void* pointer to the shared memory segment, so i cast it, add an offset to the exact location where data is written and then i simply assingn manualVar.
next i should be able to just:
MANUAL_cap1State=manualVar->mC1St;
MANUAL_cap2State=manualVar->mC2St;
MANUAL_cap3State=manualVar->mC3St;
where MANUAL_* variables are int.
then i just test with cout to see if the values have been copies and well they haven't...
any ideas why?
nass

wysota
26th September 2006, 12:51
Did you check that the shared segment got updated? For example by printf()ing the data directly from within the shared segment.

nass
26th September 2006, 12:56
isnt it sufficient looking directly at the associated file on the disk?
cause as soon as i save, i can see changes on the file... so i figure i save in the shared memory and directly the file on the disk is updated. causei surely dont write to the file.. i just 'save' to a location pointed to by the file_memory pointer (+ the offset)
nass

wysota
26th September 2006, 14:11
isnt it sufficient looking directly at the associated file on the disk?
If it seems that the segment is not updated, then it's better to check that out. There is no reason why the assignment should fail, so if it fails, there is a reason to suspect that the segment wasn't updated.