c++ - How to receive dynamic length data from a message queue? -
I have to send and receive dynamic data using the SysV message queue for university projects.
The length of the data is transmitted in a separate message, size
is already known.
And so on, I try to get data. I have to admit that I am not a C ++ expert, especially when it comes to memory allocation.
struct {long mtype; Four * mdata; } Msg; Msg.mdata = (four *) molk (size * size (four)); Msgrcv (MSGQ_ID, & amp; msg, size, MSG_ID, 0);
The problem seems to call malloc
, but I do not know how to do this.
edit
I try to send some types of read around the message queue in the OO cover < Em> should be the method. I want to read the data in the message queue in char []
or std :: string
. I now look like this (simplified).
bool wrapper :: read (char * data, int length) {struct message {long mtype; Std :: string mdata; }; Message message; Msg.mdata = std :: string (size, '\ 0'); If (MSGQCV (MSGQID, and MAG, size, MSG_ID, 0) <0) {false return; } Memcpy (data, msg.mdata.c_str (), msg.mdata.size ()); Back true; }
I am getting split split or completely corrupt data (though sometimes what I want in this data). You can not pass a pointer in the structure containing one away By luck, due to determining the size of this buffer, depending on the Its components as a You need to do something like this. To go to the other side, you have to pack the data in a consistent data array, as required by the msgsnd interface. As others have an indicator, it is not a good interface, but considering the implementation-defined behavior and alignment concerns, such a thing should be done. For example std :: string
msgrcv
, it violates the interface agreement struct {long mtype} of sufficient space to store 'plain' straight To indicate the buffer, the second parameter has been passed to
where the size is the third parameter for msgrcv
; four MDT [size];}; msgrcv
. size
may be possible alignment issues, you must admit that it is not on a system that provides this type of interface You can use the standard offsetof
macro to help determine this size. vector
Stored in a narrow form, once you have buffer Know the car, you can resize the vector
to char
and use it to capture buffer by using vector
Delete a free
or [
] A buffer manually frees you from liability.
std :: string res message () {extern size_t size; // maximum size, should be a parameter ?? Extra int MSGQ_ID; // Message Qi ID, should be a parameter ?? External Long MSG_ID; // Message type, should be a parameter ?? // ugly composition hack is required msgrcv struct RawMessage {long mtype; Four MDT [1]; }; Size_t data_offset = offset (romessage, MDAT); // message std :: vector & lt; Char & gt; Allocates the correct size buffer to Msgbuf (size + data_offset); Ssize_t bytes_read; // Read raw message if ((Bytes = Read = MSGRCV (MSGQID, and IMBF [0], Size, MSG_ID, 0)) & lt; 0) {throw MSGARCFFexpression (); } // A string encapsulates data and size, why not only return one std :: string (msgbuf.begin () + data_offset, msgbuf.begin () + data_offset + bytes_read); }
Zero SendMessage (const std :: string and data) {extern int MSGQ_ID; // Message Qi ID, should be a parameter ?? External Long MSG_ID; // Message type, should be a parameter ?? // ugly composition hack is required by msgsnd structure RawMessage {long mtype; Four MDT [1]; }; Size_t data_offset = offset (romessage, MDAT); // message std :: vector & lt; Char & gt; Msgbuf (data.size (+ + data_offset) to allocates buffers to the required size; Long MTEP = MSG_ID; Const char * mtypeptr = reinterpret_cast & lt; Char * & gt; (& Amp; mtype); Std :: copy (mtypeptr, mtypeptr + sizeof mtype, and msgbuf [0]); Std :: copy (data.begin (), data.end (), and msgbuf [data_offset]); Int results = msgsnd (MSGQ_ID, and msgbuf [0], msgbuf.size (), 0); If (results! = 0) {throw MsgSendFailedException (); }}
Comments
Post a Comment