2015-08-18 67 views
0

我试图发送(理想情况下)从一个进程到另一个2d缓冲区,通过Message Queue,但我试图首先使用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哪里再次是一维阵列双。

现在,当我检查在写入队列之前放入usb_data[20]的值时,我可以看到它们是非零整数。但是,当我从队列中读取数组并检查其值时,它们为零。林不知道是什么原因造成这个问题。我使用消息队列发送单个值,字符串和结构,所以我想我可以按照相同的过程发送数组,但这似乎并不是这样,除非我忽略了某些东西。

我的问题是,我可以通过消息队列发送数组/缓冲区,如果是,我可以正确设置它吗?

注:这是在Windows嵌入式紧凑型7环境和VS2008中开发的。

+0

dwBytesRead是否返回期望值(20,我猜?)。我怀疑ReadMsgQueue中的sizeof(data),因为它可能会返回指针的大小,即4而不是20,但我不确定。 – walkingTarget

+1

是否需要'(LPVOID)&data'?是不是'(LPVOID)数据',因为它已经是一个指向内存块的开始与双打? –

+0

我同意@Ru​​dolfs Bundulis。我想如果你结合我们的两个评论,你会看到成功。 – walkingTarget

回答

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,然后由读取的值作为表示读尽可能多的数据。

+0

现在唯一的问题是我偶尔会在缓冲区的末尾读0,但是我写了非零值到缓冲区。这将在1-3之间。不知道为什么它发生。 – Javia1492

+0

@ Javia1492也许还有一些尺寸问题?是否可以将写入大小设置为大于数据大小,并简单复制一些未初始化的内存?实际上是否缺少书面数据的一部分? –

+0

如果我缓冲20个值,1-20,并且在写入缓冲区后读取缓冲区,可能会出现这种情况,我得到了'1,2,3,4,...,16,17,0,0,0 '。数据缓冲区大小为20,读/写msgqueue的缓冲区大小设为160.'return WriteMsgQueue(hq,(LPVOID)data,160,INFINITE,0);'我不知道它可能在哪里复制未初始化数据,因为我在循环索引变量上运行所有内容,并确保它们不会超过我读/写的样本数 – Javia1492