I have a requirment to have communication between two processes using message queues. One process sends the request to another process and other process sends response.
For example one of the request is list all the filenames opened by the process. I have made interface structure as
#define LIST_NAMES 1
#define LIST_FILE_NAMES_RESP 2
struct sFileStruct {
unsigned int uiCommand;
开发者_开发技巧 unsigned long ulNoOfBytes; // Number of bytes to be parsed in cha* pointer below
char* pRecvData; // file names packed here in response.
};
sFileStruct inData;
// I am filling the data.
int inSize = sizeof(inData);
mq_send(m_qSendDesc, (char*)&inData, inSize, inPriority);
I think problem with above design is that as file names legth is changing char* pointer pointing to data is different, but size of structure is always constant, so receiver is not receving all the data and receiver is crashing while accessing the char* pointer.
I want to sent full data in one mq_send, and don't want to have static array inside structure. Is there any other way using message queues we can achieve this.
Please provide your inputs. Thanks
Receiver is crashing because it can not access your pointer which is only available for usage from sender program. You need to send the actual data to the message queue not a pointer.
You could make a wrapper over mq_send()
having char buffer allocated.
Every message you send will be serialized into this buffer and then you will pass it to mq_send
with appropriate length - sizeof(int) + sizeof(long) + strlen(pRecvData).
The receiver will read this data and deserialize it into sFileStruct.
IMHO using std::string instead of char* would be better.
Sample code (not tested):
class MQWrapper
{
std::string m_strBuffer;
public:
int Send( const sFileStruct& sfs )
{
m_strBuffer.clear();
m_strBuffer.append( static_cast<const char*> & sfs.uiCommand, sizeof(sfs.uiCommand) );
m_strBuffer.append( static_cast<const char*> & sfs.ulNoOfBytes, sizeof(sfs.ulNoOfBytes) );
m_strBuffer.append( sfs.pRecvData ); // only if it's zero-terminated string!!!
return mq_send(m_qSendDesc, m_strBuffer.c_str(), m_strBuffer.length(), inPriority);
}
char m_receiveBUffer[ BUFFER_SIZE ];
int Receive( sFileStruct& sfs )
{
int res = mq_receive( m_qSendDesc, receiveBUffer, BUFFER, outPriority );
if( res < 0 )
return res;
if( res < sizeof(int) + sizeof(long) )
return -1000; // malformed message
sfs.uiCommand = * ( static_cast<unsigned int*> (m_receiveBUffer[0]) );
sfs.ulNoOfBytes = * ( static_cast<long*> (m_receiveBUffer[ sizeof(int) ] ) );
// I don't really use this style in my work and not sure how to use it
// str::string would be much easier
int stringLen = res - sizeof(int) - sizeof(long);
sfs.pRecvData = new char [ stringLen + 1 ]; // you have to delete [] it later
if( stringLen > 0 )
strcpy( sfs.pRecvData, receiveBUffer + sizeof(int) + sizeof(long), stringLen );
ss.pRecvData[ stringLen ] = '\0'; // null terminator
return 0;
}
};
Shouldn't mq_send's second parameter be a const char* value? But you're passing a custom-written struct. I would write some code to serialize or turn the struct, if I were you, into a const char*, then use strlen to get its length and pass those two values as the second and third arguments to mq_send.
精彩评论