day5 – 进程间通信

本文详细介绍了Windows平台下的进程间通信技术,包括WM_COPYDATA消息传递、DLL共享段以及文件映射的方法。WM_COPYDATA适合小量数据传输,效率较低。DLL共享段需在同一DLL中开辟空间并设置共享属性。文件映射则允许直接操作内存来实现高效的数据交换,分为带文件和无文件两种方式。这些技术在多进程通信中各有优缺点,适用于不同的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程间通信

WM_COPYDATA

数据流向是单向的,不推荐携带大量数据。效率低下,因为他需要通过高2g物理内存进行两次拷贝。

SendMessage(hwnd,WM_COPYDATA,wParam,lParam);

其中,WM_COPYDATA对应的十六进制数为0x004A

wParam设置为包含数据的窗口的句柄。

lParam指向一个COPYDATASTRUCT的结构:

typedef struct tagCOPYDATASTRUCT {
    ULONG_PTR dwData; //用户定义数据    
    DWORD cbData; //用户定义数据的长度    
    __field_bcount(cbData) PVOID lpData; //指向用户定义数据的指针
} COPYDATASTRUCT, *PCOPYDATASTRUCT;

DLL共享段

前提:不同进程加载同一DLL

注意:定义的变量需要初始化

使用步骤

  1. dll中开辟一块空间

  2. 使用 #pragma data_seg("空间命名") ,空间开始的位置

  3. 中间定义变量

  4. 使用 #pargma data_seg() ,空间结束的位置

  5. 在开辟的空间中定义变量

  6. 将空间的属性设置为可共享

  7. 使用 /SECTION:name,[E][C][I][R][W][S][D][K][L][P][X] 设置属性

简写属性意义
EExecute允许执行代码
CConforming将部分标记为符合
IIOPL将部分标记为IOPL
RRead允许对数据进行读取操作
WWrite允许对数据进行写操作
SShared在加载映像的所有进程之间共享部分
DDiscardable将该部分标记为可丢弃
KCacheable将该部分标记为不可缓存
LPreload仅VxD; 将部分标记为预加载
PPageable将该部分标记为不可分页
XMemory-resident仅VxD; 将节标记为驻留内存

文件映射

文件操作

打开文件: CreateFile

读取文件: ReadFile

写入文件: WriteFile

HANDLE CreateFile(
  LPCTSTR lpFileName,                         // file name
  DWORD dwDesiredAccess,                      // access mode
  DWORD dwShareMode,                          // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  DWORD dwCreationDisposition,                // how to create
  DWORD dwFlagsAndAttributes,                 // file attributes
  HANDLE hTemplateFile                        // handle to template file
);

BOOL ReadFile(
  HANDLE hFile,                // handle to file
  LPVOID lpBuffer,             // data buffer
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // number of bytes read
  LPOVERLAPPED lpOverlapped    // overlapped buffer
);

BOOL WriteFile(
  HANDLE hFile,                    // handle to file
  LPCVOID lpBuffer,                // data buffer
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // number of bytes written
  LPOVERLAPPED lpOverlapped        // overlapped buffer
);

文件映射操作文件

  1. 打开文件,使用 CreateFile API
  2. 创建文件映射对象,使用 CreateFileMapping API
  3. 映射文件视图, 使用 MapViewOfFile API
  4. 通过操作内存去操作文件
  5. 使用…
  6. 取消映射,使用 UnmapViewOfFile API
  7. 关闭文件映射对象,使用 CloseHandle API
  8. 关闭文件,使用 CloseHandle API
HANDLE CreateFile(
  LPCTSTR lpFileName,                         // file name
  DWORD dwDesiredAccess,                      // access mode
  DWORD dwShareMode,                          // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  DWORD dwCreationDisposition,                // how to create
  DWORD dwFlagsAndAttributes,                 // file attributes
  HANDLE hTemplateFile                        // handle to template file
);

HANDLE CreateFileMapping(
  HANDLE hFile,                       // handle to file
  LPSECURITY_ATTRIBUTES lpAttributes, // security
  DWORD flProtect,                    // protection
  DWORD dwMaximumSizeHigh,            // high-order DWORD of size
  DWORD dwMaximumSizeLow,             // low-order DWORD of size
  LPCTSTR lpName                      // object name
);

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap  // number of bytes to map
);

BOOL UnmapViewOfFile(
  LPCVOID lpBaseAddress   // starting address
);

带文件的文件映射进程间内存共享

使用 OpenFileMapping API,取已经存在的文件映射

HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // access mode
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // object name
);

无文件的文件映射进程间内存共享

CreateFile API 使用 CreateFileMapping API代替,即可实现无文件通信.

注意:如果第一个参数hFile为 INVALID_HANDLE_VALUE 则后面的文件大小需要填写

HANDLE CreateFileMapping(
  HANDLE hFile,                       // handle to file
  LPSECURITY_ATTRIBUTES lpAttributes, // security
  DWORD flProtect,                    // protection
  DWORD dwMaximumSizeHigh,            // high-order DWORD of size
  DWORD dwMaximumSizeLow,             // low-order DWORD of size
  LPCTSTR lpName                      // object name
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值