跨进程通信的CProcessData类

在Windows编程中,跨进程通信是一个常见的需求。当需要与另一个进程中的控件交互时,例如发送消息或获取数据,通常需要使用到SendMessagePostMessage函数。然而,这些函数要求手动管理内存分配和释放,以及进程句柄的关闭,这无疑增加了编程的复杂性。为了简化这一过程,可以使用CProcessData类,这是一个模板类,它封装了跨进程通信中的数据操作。

CProcessData类简介

CProcessData类提供了一种便捷的方式来在不同进程之间传递数据。它通过封装OpenProcessVirtualAllocEx等Windows API函数,使得在不同进程间读写数据变得更加简单。

CProcessData类的构造函数允许指定目标进程的ID、访问权限、内存分配类型和内存保护属性。如果进程ID设置为0,则默认使用当前进程的ID。

CProcessData(DWORD dwProcessId = 0, DWORD dwDesiredAccess = PROCESS_ALL_ACCESS, DWORD flAllocationType = MEM_COMMIT, DWORD flProtect = PAGE_READWRITE);

WriteData方法用于将数据复制到目标进程的内存中。它接受一个引用参数,并将其内容写入到目标进程的内存地址。

BOOL WriteData(const T& data);

ReadData方法用于从目标进程的内存中读取数据。它接受一个指针参数,并将目标进程内存中的数据读取到该指针指向的变量中。

BOOL ReadData(T* data);

CProcessData类还提供了一个模板化的ReadData方法,允许从目标进程的特定内存地址读取特定类型的数据。

template BOOL ReadData(TSUBTYPE* data, LPCVOID lpData);

GetData方法用于获取在目标进程中分配的内存地址。

const T* GetData();

使用示例

假设需要向另一个进程中的日期/时间选择控件发送DTM_SETSYSTEMTIME消息。使用CProcessData类,可以简化这一过程。

SYSTEMTIME systim; // 填充systim CProcessData data(pid); data.WriteData(systim); DWORD dwResult = (DWORD)::SendMessage(hwnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)data.GetData()); if (dwResult == 0) { DWORD err = GetLastError(); // ... }

通过使用CProcessData类,不仅减少了代码量,还避免了忘记释放内存或关闭进程句柄的风险。

再比如,需要从另一个进程的Toolbar控件中获取按钮信息。使用CProcessData类,同样可以简化这一过程。

CProcessData data(pid); ::SendMessage(hwnd, TB_GETBUTTON, index, (LPARAM)data.GetData()); TBBUTTON tb; data.ReadData(&tb); CUSTOMDATA cus; data.ReadData(&cus, (LPCVOID)tb.dwData);

CProcessData类使得跨进程通信变得更加简洁和安全。

CProcessData类是一个模板类,它提供了跨进程通信中数据操作的封装。以下是类的源代码参考:

/* Author : Nishant Sivakumar Date : June 9, 2005 Info : Template class that makes it easy to use data allocated in a different process. Useful when making inter-process SendMessage/PostMessage calls. Contact : nish#voidnish.com */ // ProcessData.h #pragma once template class CProcessData { public: CProcessData(DWORD dwProcessId = 0, DWORD dwDesiredAccess = PROCESS_ALL_ACCESS, DWORD flAllocationType = MEM_COMMIT, DWORD flProtect = PAGE_READWRITE) { m_hProcess = OpenProcess(dwDesiredAccess, FALSE, dwProcessId ? dwProcessId : GetCurrentProcessId()); ASSERT(m_hProcess); if (m_hProcess) { m_lpData = VirtualAllocEx(m_hProcess, NULL, sizeof(T), flAllocationType, flProtect); ASSERT(m_lpData); } } ~CProcessData() { if (m_hProcess) { if (m_lpData) { VirtualFreeEx(m_hProcess, m_lpData, NULL, MEM_RELEASE); } CloseHandle(m_hProcess); } } BOOL WriteData(const T& data) { return (m_hProcess && m_lpData) ? WriteProcessMemory(m_hProcess, m_lpData, (LPCVOID)&data, sizeof(T), NULL) : FALSE; } BOOL ReadData(T* data) { return (m_hProcess && m_lpData) ? ReadProcessMemory(m_hProcess, m_lpData, (LPVOID)data, sizeof(T), NULL) : FALSE; } template BOOL ReadData(TSUBTYPE* data, LPCVOID lpData) { return m_hProcess ? ReadProcessMemory(m_hProcess, lpData, (LPVOID)data, sizeof(TSUBTYPE), NULL) : FALSE; } const T* GetData() { return (m_hProcess && m_lpData) ? (T*)m_lpData : NULL; } private: T m_Data; HANDLE m_hProcess; LPVOID m_lpData; };
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485