Я пытаюсь отправить (в идеале) 2d буфер из одного процесса в другой, через Очередь сообщений, но я пытаюсь сделать это сначала с 1d буфером.
Функции, вызываемые для инициализации очереди, следующие:
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;
}
Инициализация очереди в процессе 1:
HANDLE hMsgQueueR = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(true, L"CommDataStreaming");
Инициализация очереди в процессе 2:
HANDLE s_hMsgQueue_Communication = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(false,L"CommDataStreaming");
Для записи в очередь я вызываю следующие функции:
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);
куда usb_data
1d двойной массив
Чтобы прочитать из очереди, я вызываю следующие функции:
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);
куда usb_data
снова 1d двойной массив.
Теперь, когда я проверяю значения, которые помещены в usb_data[20]
прежде чем он будет записан в очередь, я вижу, что они являются ненулевыми целыми числами. Однако когда я читаю массив из очереди и проверяю его значения, они равны нулю. Я не уверен, что вызывает эту проблему. Я использовал очереди сообщений для отправки отдельных значений, строк и структур, поэтому я решил, что смогу выполнить ту же процедуру для отправки по массиву, но, похоже, это не так, если только я что-то не замечаю.
У меня вопрос: могу ли я отправлять массивы / буферы по очереди сообщений, и если да, правильно ли я их настроил?
Примечание: это разрабатывается в среде Windows 7 Compact Compact VS VS 2008.
Есть несколько проблем с предоставленным кодом.
1) Неправильные значения параметров — вам не нужно брать адрес буфера данных, так как переменная уже является указателем на начало памяти, содержащей элементы. Так что меняй (LPVOID)&data
в (LPVOID)data
,
2) Неправильный размер — sizeof
оператор вернет 4, так как это размер указателя. В вашем случае вам нужно будет передать 160 как размер (20 * sizeof(double)
).
Что касается записи с переменным размером — это становится немного сложнее, так как вам нужно знать, сколько данных нужно прочитать на другом конце. Что вы можете сделать, так это использовать, скажем, первые / первые два / первые четыре байта буфера для хранения размера, а затем продолжить работу с данными. Тогда вы можете иметь функцию, которая принимает double
массив переменной длины и записывает его. Например:
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);
}
или же
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);
}
а затем на принимающей стороне вы бы сначала зачитали unsigned int
и затем прочитайте столько данных, сколько указано значением чтения.