2010-11-25 156 views
1

我需要使用消息隊列在兩個進程之間進行通信。一個進程將請求發送到另一個進程,並且其他進程發送響應。使用消息隊列在進程之間傳遞消息

例如,其中一個請求列出了進程打開的所有文件名。我做了界面結構

#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); 

我覺得上面的設計問題是,legth正在改變字符的文件名*指針指向的數據是不同的,但結構的大小始終是恆定的,所以接收器沒有receving所有數據和接收器在訪問char *指針時崩潰。

我想在一個mq_send中發送完整的數據,並且不希望在結構中有靜態數組。有沒有其他方式使用消息隊列,我們​​可以實現這一點。

請提供您的意見。 謝謝

+1

記住:如果您縮進代碼,將格式正確的! – 2010-11-25 09:07:06

回答

1

你可以通過mq_send()分配一個包含char緩衝區的包裝。

您發送的每條消息都會被序列化到這個緩衝區,然後您將它傳遞給mq_send,長度適當 - sizeof(int)+ sizeof(long)+ strlen(pRecvData)。

接收器將讀取這些數據並將其反序列化爲sFileStruct。

恕我直言,使用std :: string而不是char *會更好。

示例代碼(未測試):

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; 
    } 
}; 
0

不應該mq_send的第二個參數是一個const char *值嗎?但是你傳遞了一個自定義編寫的結構。我會編寫一些代碼來序列化或將結構(如果我是你)轉換爲const char *,然後使用strlen獲取其長度,並將這兩個值作爲第二個和第三個參數傳遞給mq_send。

+0

對不起,它被提及在錯誤的問題,現在編輯了mq_send(m_qSendDesc,(char *)&inData,inSize,inPriority); – venkysmarty 2010-11-25 09:19:11

+0

嗨 - 你不能只是將一個結構轉換成char *來轉換它 - 你必須編碼轉換,因爲你也將int轉換爲char *。 – 2010-11-25 09:25:00

3

Receiver崩潰,因爲它無法訪問您的指針,該指針僅適用於發件人程序的使用。您需要將實際數據發送到消息隊列而不是指針。

+0

你能告訴我們如何用結構實現這一點? – venkysmarty 2010-11-25 09:20:08