Retrieving data from void *msg pointers - Resource manager

Hello,

this is my first post, so, introductions may be useful.
I’m working with QNX since 2002. I’ve writed some resource managers, created and implemented a system architecure for robotics.

Well… this last days, I’m having some problems with retrieving data from void *data pointers.

I want to discuss the best way for implementing different types of data wich the resource manager may receive.

What am I doing?

I have some structures like :

[code]struct header_t {
int a;
int b;
};

struct data_t {
int c;
int d;
};

typedef struct {
struct headerT *hea;
struct data_t *data;
} buf_t;[/code]

From a client program (sender) I do something like

[code]

buf_t *buf;

buf->hea = &header;
buf->data = &data;

write(RESMGR. buf, (sizeof(struct header_t) + sizeof(struct data_t));[/code]

From Resource Manager I want to do something like :
1 - read the header information :

resmgr_msgread(ctp, &buf->header, sizeof(buf->header), sizeof(msg->i))

2 - Check the header information
3 - read the info.

resmgr_msgread(ctp, &buf->info, sizeof(buf->info), (sizeof(msg->i) + sizeof(buf->header));

4 - Check de info
5 - do something…
6 - end

I want to discuss the ways to do this. You got a message, then you must first see wich message is this (reading the header) and then, put the information received in the right structure (based on header information).
Now, i planned to do 2 resmgr_msgread, the first one with only the header information and then, the second read for the data.

I’m getting weird pointer problems, the client sends the full information and the resource manager receives it, but the header contains useless information like if the pointer is pointing to the wrong place. :slight_smile:
But, if the client sends ONLY the header information, the information is ok but with no data after the header… :confused:

Thanx to all
Leandro Colen
GEAR - Grupo de Estudos em Automacao e Robotica
Study group for automation and robotics.
PUC-MG - Brazil

That’s because the pointer is pointing to the wrong place. You are sending the buf_t structure from the client and all it contains is pointers to addresses in the client. The approach I would use would be to make buf_t an inclusive structure - have it contain (not reference) the other structures.

typedef struct {
struct header_t header;
struct data_t data;
} buf_t;

That way the write message includes all the data.

Now having said that, there is another way to do this using the writev() function. You could create an IOV which points to each “block” and send the data without copying it. The code would look something like this:

...
iov_t iov[3];

iov[0].iov_base = &type;
iov[0].iov_len = sizeof(type);

iov[1].iov_base = &header;
iov[1].iov_len = sizeof(header);

iov[2].iov_base = &data;
iov[2].iov_len = sizeof(data);

writev( RESMGR, iov, 3 );

This causes the kernel to send the data directly from your structures without copying it into a buffer first. On the recieve end, it will appear like one large buffer, containing both chunks of data in a row. If you want the received data to go into separate buffers, you can use MsgRecievev();

In your case, you would do a resmgr_msgread() on the type structure, then do a resmgr_msgread() on each of the chunks, putting them into the appropriate receiving structures.

Hopefully this will help,

Rick…

To add to ricks’ comment. QNX uses virtual address space. That means each program get to live in it’s own private address space. Thus when a pointer points at address 0x10000 for example that’s a virtual pointer which physical points to somewhere else. Another program may also have a pointer 0x10000 which point to a different locatition the the other program. That’s why you cannot transfer pointer from program to program (but you can within thread of the same program). Even if the pointer points to a shared memory region (mmap) you still can’t do it since the common memory space is map to a different virtual space within the processes.

Thank you for the help and information.
The problem was solved just changing the pointers as rick instructed.

I have not tried the IOV yet because the same algorithm I’m using on resource manager will be used in another application running in another plataform (win and linux).

Cheers,
Leandro