进程间通信
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
注意:定义的变量需要初始化
使用步骤
-
dll中开辟一块空间
-
使用
#pragma data_seg("空间命名")
,空间开始的位置 -
中间定义变量
-
使用
#pargma data_seg()
,空间结束的位置 -
在开辟的空间中定义变量
-
将空间的属性设置为可共享
-
使用
/SECTION:name,[E][C][I][R][W][S][D][K][L][P][X]
设置属性
简写 | 属性 | 意义 |
---|---|---|
E | Execute | 允许执行代码 |
C | Conforming | 将部分标记为符合 |
I | IOPL | 将部分标记为IOPL |
R | Read | 允许对数据进行读取操作 |
W | Write | 允许对数据进行写操作 |
S | Shared | 在加载映像的所有进程之间共享部分 |
D | Discardable | 将该部分标记为可丢弃 |
K | Cacheable | 将该部分标记为不可缓存 |
L | Preload | 仅VxD; 将部分标记为预加载 |
P | Pageable | 将该部分标记为不可分页 |
X | Memory-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
);
文件映射操作文件
- 打开文件,使用
CreateFile
API - 创建文件映射对象,使用
CreateFileMapping
API - 映射文件视图, 使用
MapViewOfFile
API - 通过操作内存去操作文件
- 使用…
- 取消映射,使用
UnmapViewOfFile
API - 关闭文件映射对象,使用
CloseHandle
API - 关闭文件,使用
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
);