點(diǎn)對點(diǎn)消息隊列函數(shù):用于WinCE的IPC機(jī)制
本文說明點(diǎn)對點(diǎn)消息隊列 — 一個鮮為人知的 IPC 機(jī)制,它高效、靈活,并且專用于 Windows CE 4.0 及其更高版本。此外,本文還說明如何設(shè)計和使用托管包裝,使 .NET Compact Framework 應(yīng)用程序中的 IPC 極其簡便。
開發(fā)人員能夠以多種方式使用點(diǎn)對點(diǎn)消息隊列。開發(fā)人員通常在無法宿主 .NET Compact Framework 運(yùn)行庫的情況下使用 IPC 作為替代方案(本機(jī)進(jìn)程通過 IPC 與托管進(jìn)程進(jìn)行通訊),并且點(diǎn)對點(diǎn)消息隊列是***選擇。點(diǎn)對點(diǎn)消息隊列還可以與操作系統(tǒng)進(jìn)行交互,例如,用于獲取電源信息。本文不介紹點(diǎn)對點(diǎn)消息隊列的其他用途,這些用途留待您了解核心原理之后自行探究。
本部分以一個您易于了解的方式描述點(diǎn)對點(diǎn)消息隊列函數(shù)。
當(dāng)開發(fā)人員使用 IPC 時,一個進(jìn)程創(chuàng)建用于寫入的隊列,另一個進(jìn)程創(chuàng)建用于讀取的隊列 (CreateMsgQueue)。在雙向 IPC 通訊中,開發(fā)人員在通訊的每一端(在兩個獨(dú)立的進(jìn)程間或同一進(jìn)程的兩個對象間)都需要兩個隊列。
在使用點(diǎn)對點(diǎn)消息隊列時,開發(fā)人員可以采用若干種方法。例如,有用于讀取 (ReadMsgQueue)、寫入 (WriteMsgQueue) 和關(guān)閉隊列 (CloseMsgQueue) 的方法。此外,如果除了隊列句柄之外,開發(fā)人員還具有擁有該隊列的源進(jìn)程的句柄,那么他們就可以打開現(xiàn)有隊列 (OpenMsgQueue)。開發(fā)人員可以查詢一些統(tǒng)計信息 (GetMsgQueueInfo),***可以使他們的應(yīng)用程序等待隊列句柄 (WaitForSingleObject) 接收信號,以便確定隊列中是否有數(shù)據(jù)。
打開一個現(xiàn)有隊列時,開發(fā)人員只能指定一個選項(xiàng) — 該隊列是用于讀還是用于寫。當(dāng)創(chuàng)建隊列時,開發(fā)人員可以指定其他參數(shù):名稱 (lpszName) 和選項(xiàng)(類型為 MSGQUEUOPTIONS 的 lpOptions)。隊列選項(xiàng)包括以下內(nèi)容:單個消息的***大小 (cbMaxMessage)、隊列中消息的隨機(jī)***數(shù)量 (dwMaxMessages)、是否應(yīng)該動態(tài)分配緩沖區(qū)(dwFlags、MSGQUEUE_NOPRECOMMIT),以及閱讀器是否可以在沒有編寫器的情況下存在(dwFlags、MSGQUEUE_ALLOW_BROKEN),反之亦然。關(guān)閉隊列時,開發(fā)人員將句柄作為參數(shù) ( hMsgQ )。
寫入隊列需要一個指針 ( lpBuffer )、消息中的字節(jié)數(shù) ( cbDataSize )、超時 ( dwTimeout ),以及該消息是否是一個警告消息( dwFlags 、MSGQUEUE_MSGALERT)。從隊列讀取需要:傳入一個緩沖區(qū) (lpBuffer)、緩沖區(qū)的大小 ( cbBufferSize ),以及一個超時值 ( dwTimeout );因此,可獲悉實(shí)際字節(jié)數(shù) ( lpNumberOfBytesRead ) 以及該消息是否為一個警告( pdwFlags 、MSGQUEUE_MSGALERT)。注意,超時是以毫秒計算的;0 表示“不阻塞”,而 INFINITE (-1) 表示“阻塞,直到操作完成或隊列狀態(tài)更改”。如果成功,讀函數(shù)和寫函數(shù)都返回 TRUE;否則,返回 FALSE。在后一種情況中,您可以獲得擴(kuò)展的錯誤信息 (GetLastError)。函數(shù)返回 FALSE 的可能原因有:緩沖區(qū)太小 (ERROR_INSUFFICIENT_BUFFER);沒有編寫器或閱讀器,且開發(fā)人員未按前面段落中所述的那樣指定 MSGQUEUE_ALLOW_BROKEN (ERROR_PIPE_NOT_CONNECTED);或者發(fā)生超時 (ERROR_TIMEOUT)。對于 WriteMsgQueue,如果未按前面段落中所述的那樣指定 MSGQUEUE_NOPRECOMMIT,則也可能得到錯誤 ERROR_OUTOFMEMORY。
可調(diào)用 GetMsgQueueInfo 來獲得包含統(tǒng)計信息的結(jié)構(gòu) (MSGQUEUEINFO)。該結(jié)構(gòu)包含的信息包括開發(fā)人員在創(chuàng)建隊列時傳入的一些參數(shù):消息的***大小 (cbMaxMessage)、消息的***數(shù)量 (dwMaxMessages)、是否應(yīng)該動態(tài)分配緩沖區(qū)(dwFlags、MSGQUEUE_NOPRECOMMIT),以及閱讀器是否可以在沒有編寫器的情況下存在(dwFlags、MSGQUEUE_ALLOW_BROKEN),反之亦然。此外,該結(jié)構(gòu)還包含以下內(nèi)容:當(dāng)前隊列中非警告信息的數(shù)量 (dwCurrentMessages)、隊列中曾經(jīng)存在消息的***數(shù)量 (dwMaxQueueMessages)、當(dāng)前閱讀器的數(shù)量 (wNumReaders),以及當(dāng)前編寫器的數(shù)量 (wNumWriters)。
【編輯推薦】