c++ipcmessage-queuewindows-embedded-compact

Sending buffer over message queue


I am trying to send (ideally) a 2d buffer from one process to another, over a Message Queue, but i am attempting to do it first with a 1d buffer.

The functions called to initialization the queue are the following:

HANDLE MsgQueueCommunicator::InitMessageQueue_data(bool IsRead,wchar16_t* wQueueName)
{

  MSGQUEUEOPTIONS msgopts;
  msgopts.dwSize        = sizeof(MSGQUEUEOPTIONS);   
  msgopts.dwFlags       = MSGQUEUE_ALLOW_BROKEN;//0;
  msgopts.dwMaxMessages = 0;
  msgopts.cbMaxMessage  = sizeof(data[20]);   
  msgopts.bReadAccess   = IsRead;   

  HANDLE hq = CreateMsgQueue(wQueueName, &msgopts);
  if ( hq == NULL )   
  {    
      return NULL;
  }   
  return hq;
}

Queue initialization in process 1:

 HANDLE hMsgQueueR = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(true, L"CommDataStreaming");

Queue initialization in process 2:

 HANDLE s_hMsgQueue_Communication = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(false,L"CommDataStreaming");

To write to the queue, i call the following functions:

BOOL MsgQueueCommunicator::Write_Array_To_Queue(HANDLE hq,double data[20])
{
    return WriteMsgQueue(hq,(LPVOID)&data, sizeof(data),INFINITE,0);
}

MsgQueueCommunicator::getInstance()->Write_Array_To_Queue(s_hMsgQueue_Communication, usb_data);

Where usb_data is a 1d double array.

To read from the queue, i call the following functions:

BOOL MsgQueueCommunicator::Read_Array_From_Msg_Queue(HANDLE hq,double data[20])
{
    DWORD dwBytesRead;
    DWORD dwFlags;
    return ReadMsgQueue(hq, (LPVOID)&data, sizeof(data), &dwBytesRead, INFINITE, &dwFlags);
}

MsgQueueCommunicator::getInstance()->Read_Array_From_Msg_Queue(hMsgQueueR, usb_data);

Where usb_data is again a 1d double array.

Now, when i check the values that are placed into usb_data[20] before it is written to the queue, i can see that they are non-zero integers. However, when i read the array from the queue and check its values, they are zero. Im not sure what is causing this issue. I've used message queues to send single values, strings, and structs, so i figured i would be able to follow the same procedure to send over an array, but this does not seem to be the case, unless i am overlooking something.

My question is, can i send arrays/buffers over a message queue, and if yes, have I set it up properly?

Note:This is being developed in a windows embedded compact 7 environment and VS2008.


Solution

  • There are several problems with the code provided.

    1) Wrong parameter values - you do not need to take an address of the data buffer since the variable is already a pointer to the beginning of the memory that contains the elements. So change (LPVOID)&data to (LPVOID)data.

    2) Wrong size - the sizeof operator will return 4 since that is the size of the pointer. In your case you would need to pass 160 as the size (20 * sizeof(double)).

    As for variable size writes - this gets a bit more complicated since you need to know how much data to read at the other end. What you can do is use lets say first/first two/first four bytes of the buffer to contain size and then proceed with the data. Then you can have a function that accepts a double array of variable length and writes it. For example:

    BOOL Write_Array_To_Queue(HANDLE hq,double data[], unsigned int count)
    {
        size_t buffer_size = sizeof(count) + count * sizeof(double);
        BYTE* buffer = new BYTE[buffer_size];
        memcpy(buffer, &count, sizeof(count));
        memcpy(buffer + sizeof(count), &data, sizeof(double) * count);
        return WriteMsgQueue(hq,(LPVOID)buffer, buffer_size,INFINITE,0);
    }
    

    or

    BOOL Write_Array_To_Queue(HANDLE hq,double data[], unsigned int count)
    {
        return WriteMsgQueue(hq,(LPVOID)&count, sizeof(count),INFINITE,0) && WriteMsgQueue(hq,(LPVOID)data, sizeof(double) * count,INFINITE,0);
    }
    

    and then in the receiving side you would first read out an unsigned int and then read as much data as denoted by the read value.