首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

Windows 進程間通訊詳解:WM_COPYDATA、共享內存、管道與套接字

     編輯:C++ 入門

Windows 進程間通訊(IPC)核心機制全解析

在 Windows 系統中,進程擁有獨立的虛擬地址空間,無法直接共享記憶體。為了實現數據交換與協作,必須借助核心物件或系統提供的通訊機制。本文將深入剖析 WM_COPYDATA 訊息機制,並系統梳理 Windows 下主流的十種進程間通訊方式,幫助開發者根據場景選擇最佳方案。

一、WM_COPYDATA:最經典的訊息傳遞方式

WM_COPYDATA 是 Win32 API 中專為進程間數據傳輸設計的標準訊息。它允許發送進程將任意二進制數據安全地複製到接收進程的地址空間中。

核心結構體 COPYDATASTRUCT

typedef struct tagCOPYDATASTRUCT {
    DWORD dwData;  // 32 位自定義數據,可用於標識數據類型
    DWORD cbData;  // lpData 指向的數據大小(位元組數)
    PVOID lpData;  // 指向實際數據的指標
} COPYDATASTRUCT;

發送流程與關鍵點

推薦使用 SendMessage 而非 PostMessage,因為 SendMessage 是同步阻塞的:接收進程處理完訊息並複製數據前,發送進程會一直等待,確保數據在傳輸過程中不被修改或釋放。

LRESULT SendMessage(
    HWND hWnd,      // 接收進程的視窗句柄
    UINT Msg,       // WM_COPYDATA
    WPARAM wParam,  // 發送進程的視窗句柄
    LPARAM lParam   // 指向 COPYDATASTRUCT 的指標
);

開發時必須注意的三大禁忌:

  1. 發送後,發送進程的其他執行緒不得修改該數據區域,直到 SendMessage 返回。
  2. 傳輸的數據中絕不能包含接收進程無法訪問的物件指標/引用,如 HDC、HBITMAP 等 GDI 物件句柄,它們在進程邊界外失效。
  3. 接收端視窗句柄可透過 FindWindow(NULL, "接收進程視窗標題") 獲取。

接收端實現範例

在消息映射表中添加 ON_WM_COPYDATA(),並實現處理函數:

BOOL CCanCollectorDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) {
    char szBuffer[300];
    memset(szBuffer, 0, sizeof(szBuffer));
    sprintf(szBuffer, "dwData:%d cbData:%d\r\nlpData:0x%08x = %s\r\n\r\n",
            pCopyDataStruct->dwData, pCopyDataStruct->cbData,
            (PVOID)pCopyDataStruct->lpData, (char*)pCopyDataStruct->lpData);
    // 實際業務邏輯處理...
    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

二、Windows 十大進程間通訊方式綜述

以下按適用場景與複雜度分類整理:

1. 訊息驅動類(需視窗句柄)

  • 標準 Windows 訊息 / WM_COPYDATA:簡單、同步、適合少量數據,接收端必須有視窗。
  • 動態數據交換 (DDE):16 位時代產物,基於全域記憶體與訊息,Win32 下已不推薦使用。

2. 記憶體共享類(高效、需同步)

  • 共享內存:透過 CreateFileMapping + MapViewOfFile 建立命名/匿名映射區。最快的 IPC 方式,但必須搭配互斥體等同步物件防止競態條件。分「Peer-to-Peer」(各進程嘗試創建,檢查 ERROR_ALREADY_EXISTS)與「Client/Server」(僅 Server 創建初始化)兩種模式。

3. 管道類(流式、單/雙向)

  • 匿名管道:單向、僅限親緣關係進程(父子進程),本機通訊。
  • 命名管道:雙向、跨網路、支援多客戶端、可整合 I/O 完成埠,適合高併發服務端。

4. 系統核心物件類

  • 郵件槽:廣播式、不可靠、單向、跨主機,Win9x 僅支援客戶端角色。
  • 剪貼板:早期簡易方式,CWnd 封裝支援,現極少用於程式間通訊。

5. 網路與遠程類(跨機器、跨平台)

  • Windows Sockets (Winsock):功能涵蓋管道,且遵循 TCP/IP 標準,實現跨作業系統通訊。
  • Internet 通訊 (WinINet/WinHTTP):基於 HTTP/FTP 協定,適合檔案上傳下載、REST API 呼叫。
  • RPC (遠程過程呼叫):封裝網路細節,讓遠程呼叫如本地函數,但 Microsoft 實現與 UNIX RPC 不相容,現多改用 gRPC/Thrift 等跨平台方案。

6. 傳統串/並口通訊

透過 COM/LPT 埠進行硬體級通訊,屬邊緣場景,不再贅述。

三、通用 IPC 模型對照(跨平台視角)

從作業系統原理看,進程間通訊本質上可歸納為七大經典模型:

模型特點典型應用
管道半雙工、單向、僅限親緣進程Shell 管線 ls | grep
有名管道半雙工、無親緣限制本機服務通訊
信號量計數器、同步/互斥資源池控制
消息佇列鏈表結構、核心持久化、帶格式異步任務分發
信號非同步通知、處理複雜進程控制
共享內存最快、需額外同步機制大數據高頻交換
套接字跨主機、跨平台、網路標準分散式系統

四、選型建議

  • 同機、小數據、簡單同步:WM_COPYDATA 或命名管道。
  • 同機、大數據、高性能:共享內存 + 互斥體/事件。
  • 跨網路、異構系統:TCP Socket / gRPC / REST API。
  • 廣播通知、不可靠可接受:郵件槽。
  • 父子進程標準輸入輸出重導向:匿名管道。

掌握各機制的優劣與適用邊界,是構建健壯、高效 Windows 應用的關鍵基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved