2015-08-18 85 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